2015-10-16 41 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; 

,我怎么能得到所有客户谁仅仅基于第二查询中指定的期间做了他们的第一次购买。我如何使用这两个查询来做到这一点?谢谢。

编辑#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; 

是有这样做的更好的办法?

编辑2:

首先查询是谁在我们的商店从一开始的时候进行购买所有客户的清单。

第二个查询是所有仅在特定月份进行购买的客户的列表。

根据这2条查询,我想列出第一次在特定月份进行购买的所有客户。

编辑#3: 也许我不是很清楚我想达到什么,所以让我详细说明一下。

我有一个名为ps_orders的表,它从一开始就存储所有的事务记录。从ps_orders我在下面列特别感兴趣:

  • id_customer
  • id_order
  • invoice_date

我想知道时间有多少首先从给定时间内的买家。例如:

我想知道有多少客户是2015年1月1日和1月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; 

如何有史以来结果包括在早日购买的客户(例如,客户编号1234可能在前一年购买)。不过,我只对第一时间买家感兴趣。请参阅编辑#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' 

应该工作,不是吗?如果你想要的只是美国消费者第一次购买的日期,我不知道这些全部购买是如何相关的。

因为它似乎你想要的客户名称和电子邮件为好,为自己

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