2015-10-16 4 views
1

У меня есть 2 запросов, то первый запрос к списку всех клиентов, которые сделали покупки с самого начала времен:Mysql запрашивая Подмножество данных

SELECT o.id_customer, CONCAT(c.firstname, ' ', c.lastname) AS fullname, c.email, COUNT(o.id_customer) AS 'total' 
FROM ps_orders AS o 
LEFT JOIN ps_order_state_lang AS osl ON o.current_state = osl.id_order_state 
LEFT JOIN ps_customer AS c ON o.id_customer = c.id_customer 
WHERE o.current_state IN(2,4,5) 
AND osl.id_lang = 2 
AND o.invoice_date BETWEEN '2014-01-01' AND '2015-09-30' 
GROUP BY o.id_customer 
ORDER BY total DESC; 

Хотя второй запрос к списку всех клиентов, которые сделали покупка на определенный период времени:

SELECT c.id_customer, CONCAT(c.firstname, ' ', c.lastname) AS fullname, COUNT(c.id_customer) AS total 
FROM ps_orders AS o 
LEFT JOIN ps_customer AS c ON o.id_customer = c.id_customer 
WHERE o.invoice_date BETWEEN '2015-01-01' AND '2015-01-31' 
AND o.current_state IN (2,4,5) 
GROUP BY c.id_customer 
ORDER BY total DESC; 

основываясь на этом, как я могу получить все клиенты, которые только сделали свою первую покупку на основе периода, указанного на втором запросе. Как я могу это сделать, используя эти 2 запроса? Благодарю.

EDIT # 1

Мое текущее решение заключается в следующем:

SELECT a.id_customer, a.fullname, a.total AS 'this_month', b.total AS 'all_time' 
FROM (
    SELECT c.id_customer, CONCAT(c.firstname, ' ', c.lastname) AS fullname, COUNT(c.id_customer) AS total 
    FROM ps_orders AS o 
    LEFT JOIN ps_customer AS c ON o.id_customer = c.id_customer 
    WHERE o.invoice_date BETWEEN '2015-01-01' AND '2015-01-31' 
    AND o.current_state IN (2,4,5) 
    GROUP BY c.id_customer 
    HAVING COUNT(c.id_customer) < 2 
    ORDER BY total DESC 
) AS a 
LEFT JOIN (
    SELECT o.id_customer, CONCAT(c.firstname, ' ', c.lastname) AS fullname, c.email, COUNT(o.id_customer) AS 'total' 
    FROM ps_orders AS o 
    LEFT JOIN ps_order_state_lang AS osl ON o.current_state = osl.id_order_state 
    LEFT JOIN ps_customer AS c ON o.id_customer = c.id_customer 
    WHERE o.current_state IN(2,4,5) 
    AND osl.id_lang = 2 
    AND o.invoice_date BETWEEN '2013-12-31' AND '2015-01-01' 
    GROUP BY o.id_customer 
    HAVING COUNT(o.id_customer) < 2 
    ORDER BY total DESC 
) AS b ON b.id_customer = a.id_customer 
ORDER BY all_time DESC; 

есть лучший способ сделать это?

EDIT 2:

Первый запрос список всех клиентов, которые сделали покупку в нашем магазине от начала времен.

Второй запрос - это список всех клиентов, которые совершили покупки только за определенный месяц.

Основываясь на этих двух запросах, я хотел бы перечислить всех клиентов, совершивших покупки в конкретный месяц в первый раз.

EDIT # 3: Возможно, я был не очень доволен тем, чего хочу достичь, поэтому позвольте мне подробнее остановиться.

У меня есть таблица с именем ps_orders, которая хранит всю запись транзакции с самого начала. От ps_orders я особенно заинтересованных в следующей колонке:

  • id_customer
  • id_order
  • invoice_date

Я хочу знать, сколько первый раз покупатели из определенного периода времени. Например:

Я хочу знать, сколько клиент первый раз покупатель в период с 01 января 2015 года и 31 января 2015 года следующий запрос перечисляет все заказы, которые сделаны между этой точной датой:

SELECT c.id_customer, CONCAT(c.firstname, ' ', c.lastname) AS fullname, COUNT(c.id_customer) AS total 
FROM ps_orders AS o 
LEFT JOIN ps_customer AS c ON o.id_customer = c.id_customer 
WHERE o.invoice_date BETWEEN '2015-01-01' AND '2015-01-31' 
AND o.current_state IN (2,4,5) 
GROUP BY c.id_customer 
ORDER BY total DESC; 

Как когда-либо результат включает клиента, совершившего покупки в более раннюю дату (например, Cust ID 1234, возможно, приобрел в предыдущем году). Однако меня интересует только первый покупатель в течение этого периода времени. Пожалуйста, смотрите EDIT # 1, чтобы увидеть мое текущее решение (оно содержит некоторые недопустимые данные, но я думаю, что я получаю близко к тому, что я хочу)

+0

Невозможно понять вопрос «первая покупка на основе периода, указанного на втором запрос "? – nik

+0

Пожалуйста, см. Мою Редактировать # 2 спасибо – Jeremy

ответ

1

Что-то вроде

SELECT o.id_customer, MIN(o.invoice_date) first_purchase 
FROM ps_orders AS o 
GROUP BY o.id_customer 
HAVING first_purchase BETWEEN '2015-01-01' AND '2015-01-31' 

должны работать, не так ли? Я не понимаю, насколько важны покупки за все время, если все, что вам нужно, это дата, когда ustomer совершил первую покупку.

Так как кажется, вы хотите, чтобы имя клиента и адрес электронной почты, а также использовать этот начальный запрос для создания таблицы объединения для себя

SELECT c.id_customer, CONCAT(c.firstname, ' ', c.lastname) AS fullname, c.email, firsts.first_purchase 
FROM (
    SELECT 
     o.id_customer cid, 
     MIN(o.invoice_date) first_purchase 
    FROM ps_orders AS o 
    GROUP BY o.id_customer 
    HAVING first_purchase BETWEEN '2015-01-01' AND '2015-01-31' 
) firsts 
LEFT JOIN customer c ON firsts.cid = c.id_customer 
# If you prefer you may replace the HAVING above with a WHERE here 
# WHERE first_purchase BETWEEN '2015-01-01' AND '2015-01-31' 
+0

Спасибо @Thernys, это удивительно короткий запрос. Можете ли вы подробнее рассказать о MIN() здесь? Я не знал, что это можно использовать таким образом, поскольку, насколько я знаю, MIN используется, если я хочу найти минимальное значение из набора записей. – Jeremy

+0

MIN является одной из [агрегатных функций MySQL] (https://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html), и да, она используется для поиска минимального значения из набор значений (столбец таблицы). В вашем случае вы хотите найти минимальное значение соответствующего набора дат (наименьшая/самая ранняя дата, найденная для покупки клиента). – Thernys

+0

@Jeremy Я не знал, нужны ли ваши 'this_month' и' all_time' итоговые данные или просто используются как средство для достижения цели. Разумеется, они могут быть обработаны и в этом запросе. – Thernys

Смежные вопросы