Mysql查询数据子集

时间:2015-10-16 08:00:31

标签: mysql prestashop

我有2个查询,第一个查询是列出从一开始就购买的所有客户:

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:

首先查询是从一开始就在我们的商店购物的所有客户的列表。

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

基于这两个查询,我想列出所有第一次在特定月份购物的客户。

编辑#3:编辑#3: 也许我对自己想要实现的目标不是很清楚,所以让我详细说明一下。

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

  • id_customer
  • id_order
  • invoice_date

我想知道在给定时间内有多少首次购买者。例如:

我想知道2015年1月1日到2015年1月31日期间有多少客户是首次购买。以下查询列出了在该确切日期之间所做的所有订单:

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;

结果如何包括在较早日期购物的客户(例如,客户ID 1234可能在上一年购买)。但是我只对这段时间内的第一次买家感兴趣。请参阅编辑#1以查看我当前的解决方案(它包含一些无效数据,但我认为我接近我想要的)

1 个答案:

答案 0 :(得分: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'