[РЕШЕНО] Помогите с докрутить sql-запрос к нескольким таблицам (drupal6 + ubercart)

Главные вкладки

Аватар пользователя WiseMan WiseMan 13 октября 2013 в 22:36

Всем привет. Давненько тут не был.

Помогите докрутить запрос для 6-го друпала + уберкарт.

Имеем стандартные таблицы
uc_cart_products (данные корзин)
users
uc_products

Требуется составить таблицу со списком пользователей, где для каждого пользователя будет отражено:
-id-пользователя
-сумма товара в корзине
-кол-во товара в корзине
-дата последнего изменения в корзине

Пока сделал вот так:

<?php$sql = "SELECT u.uid, 
  (SELECT COUNT(DISTINCT(cart_item_id)) FROM {uc_cart_products} as o WHERE o.cart_id = u.uid) as qty_list_products, 
  (SELECT SUM(qty) FROM {uc_cart_products} as ps WHERE cart_id = u.uid) as total_products 
  FROM {users} as u WHERE u.uid > 0 GROUP BY u.uid";?>

Но это не все данные - нужна еще сумма товаров (по розничной цене поле sell_price из таблицы uc_products) и дата последнего изменения в корзине (поле changed в таблице uc_cart_products).

Цену товара достаточно напрямую, без учета атрибутов, но если поможете с атрибутами - респект.

Помогите улучшить и расширить запрос под pager_query().

[РЕШЕНИЕ]
SELECT u.uid, u.name,
COUNT(ucp.cart_item_id) as qty_list_products,
SUM(ucp.qty) as qty,
SUM(ucp.qty * up.sell_price) as sumprice,
MAX(ucp.changed) as changed
FROM {users} u
LEFT JOIN {uc_cart_products} ucp ON ucp.cart_id = u.uid
LEFT JOIN {uc_products} up ON up.nid = ucp.nid
WHERE u.uid > 0 GROUP BY u.uid

Комментарии

Аватар пользователя deb deb 14 октября 2013 в 6:14

SELECT u.uid,
COUNT(ucp.cart_item_id),
SUM(ucp.qty),
SUM(up.price),
MAX(ucp.changed)
FROM users u
LEFT JOIN uc_cart_products ucp ON ucp.cart_id = u.uid
LEFT JOIN uc_products up ON up.product_id = ucp.cart_item_id
GROUP BY u.uid

Аватар пользователя WiseMan WiseMan 14 октября 2013 в 10:58

Благодарю, но почему-то не срабатывает запрос. Ошибок не выдает, но и результата нет.

Для дебага еще пробовал так:

<?php
$sql 
db_result(db_query("SELECT u.uid,
COUNT(ucp.cart_item_id),
SUM(ucp.qty),
SUM(up.price),
MAX(ucp.changed)
FROM users u
LEFT JOIN uc_cart_products ucp ON ucp.cart_id = u.uid
LEFT JOIN uc_products up ON up.product_id = ucp.cart_item_id
GROUP BY u.uid"
));

drupal_set_message('<pre>' print_r($sql,1) . '</pre>''warning'TRUE);
?>

Хотя нужна совместимость с:

<?php
  $header 
= array(
    array(
'data' => t('#')),
    array(
'data' => t('Customer'), 'field' => "uid"),
    array(
'data' => t('Qty list products'), 'field' => 'cart_item_id'),
    array(
'data' => t('Sum qty'), 'field' => 'qty'),
    array(
'data' => t('Cart Total sum price'), 'field' => 'price'),
    array(
'data' => t('Cart changed'), 'field' => 'changed''sort' => 'desc'),
  );

$customers pager_query($sql tablesort_sql($header), $page_size0);

while (

$customer db_fetch_array($customers)) { 
..
постороение таблицы.. 
}
?>
Аватар пользователя bsyomov bsyomov 14 октября 2013 в 11:47

Зачем пытаться получить все эти данные в одном запросе?
Разбейте задачу на несколько запросов. Будет проще и вам и mysql. Smile

Аватар пользователя WiseMan WiseMan 14 октября 2013 в 12:01

bsyomov wrote:
Зачем пытаться получить все эти данные в одном запросе?
Разбейте задачу на несколько запросов. Будет проще и вам и mysql. =)

Мне точно не проще )) т.к. лишнюю логику запросов простраивать надо, а у меня с запросами сложно совсем Sad

Я начал делать по аналогии из модуля uc_report в уберкарте:

<?php
$sql 
"SELECT u.uid, u.name, ou.$first_name, ou.$last_name
(SELECT COUNT(DISTINCT(order_id)) FROM {uc_orders} as o 
WHERE o.uid = u.uid AND o.order_status IN 
$order_statuses) as orders, 
(SELECT SUM(qty) FROM {uc_order_products} as ps LEFT JOIN {uc_orders} as os ON ps.order_id = os.order_id 
WHERE os.order_status IN 
$order_statuses AND os.uid = u.uid) as products, 
(SELECT SUM(ot.order_total) FROM {uc_orders} as ot 
WHERE ot.uid = u.uid AND ot.order_status IN 
$order_statuses) as total, 
ROUND((SELECT SUM(ot.order_total) FROM {uc_orders} as ot 
WHERE ot.uid = u.uid AND ot.order_status IN 
$order_statuses)/(SELECT COUNT(DISTINCT(order_id)) 
FROM {uc_orders} as o WHERE o.uid = u.uid AND o.order_status IN 
$order_statuses), 2) as average 
FROM {users} as u LEFT JOIN {uc_orders} as ou ON u.uid = ou.uid WHERE u.uid > 0 GROUP BY u.uid"
;
?>

На мой взгляд изящно извлекает статистику продаж по всем клиентам в один проход.

Поможете смоделировать?

Аватар пользователя WiseMan WiseMan 14 октября 2013 в 12:16

deb wrote:
Выполните в phpmyadmin. Проверьте имена полей в запросе, я их писал наугад.

ага, точно. Смотрю.

Уже вижу что id-продукта хранится не в отдельном поле, а внутри поля data в виде:
a:3:{s:10:"attributes";a:2:{i:9;s:2:"92";i:16;s:3:"176";}s:9:"shippable";s:1:"0";s:6:"module";s:10:"uc_product";}

Как понимаю, придется отдельным запросом извлекать.

Аватар пользователя deb deb 14 октября 2013 в 12:30

"WiseMan" wrote:
Уже вижу что id-продукта хранится не в отдельном поле, а внутри поля data в виде:
a:3:{s:10:"attributes";a:2:{i:9;s:2:"92";i:16;s:3:"176";}s:9:"shippable";s:1:"0";s:6:"module";s:10:"uc_product";}

Ну, уберкарт конечно писали рукожопы, но не до такой же степени.. Посмотрел модули уберкарта, запрос похоже должен выглядеть так:
SELECT u.uid,
COUNT(ucp.cart_item_id),
SUM(ucp.qty),
SUM(ucp.qty * up.sell_price),
MAX(ucp.changed)
FROM users u
LEFT JOIN uc_cart_products ucp ON ucp.cart_id = u.uid
LEFT JOIN uc_products up ON up.nid = ucp.nid
GROUP BY u.uid

Аватар пользователя WiseMan WiseMan 14 октября 2013 в 12:39

deb wrote:
Ну, уберкарт конечно писали рукожопы, но не до такой же степени.. Посмотрел модули уберкарта, запрос похоже должен выглядеть так:...

ошибался. Поправил по вашему, проверя..

Аватар пользователя deb deb 14 октября 2013 в 12:39

Зачем вы вообще смотрите в эту дату? У них ID продукта это ID ноды, поле nid таблицы uc_products.
Я выделил жирным изменения.

Аватар пользователя WiseMan WiseMan 14 октября 2013 в 13:39

deb wrote:
Зачем вы вообще смотрите в эту дату? У них ID продукта это ID ноды, поле nid таблицы uc_products.
Я выделил жирным изменения.

Все получилось. Благодарю!