【问题标题】:Mysql Querying A Subset of DataMysql查询数据子集
【发布时间】:2015-10-16 08:00:30
【问题描述】:

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

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
  • 发票日期

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

我想知道在 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 可能在前一年购买)。但是,我只对那段时间内的第一次购买者感兴趣。请参阅 EDIT #1 以查看我当前的解决方案(它包含一些无效数据,但我认为我正在接近我想要的)

【问题讨论】:

  • 无法理解“第一次购买基于第二次查询指定的期限”的问题?
  • 请看我的编辑#2,谢谢

标签: mysql prestashop


【解决方案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'

【讨论】:

  • 感谢@Thernys,令人惊讶的是,这是一个简短的查询。你能在这里详细说明一下 MIN() 吗?我不知道它可以以这种方式使用,因为据我所知,如果我想从记录集中找到最小值,则使用 MIN。
  • MIN 是MySQL aggregate functions 之一,是的,它用于从一组值(表列)中找到最小值。在您的情况下,您希望找到相关日期集的最小值(为客户购买找到的最小/最早日期)。
  • @Jeremy 我不确定您的this_monthall_time 总数是所需数据还是仅用作达到目的的手段。当然,它们也可以用于此查询。
  • 我想我没有从您的查询中得到想要的结果。但也许我对我的问题不是很清楚。请参阅编辑#3,我希望这次我能更好地解释我的问题。感谢您的帮助..!
  • this_month 和 all_time 列只是为了让我快速检查特定客户在给定期间仅购买一次,并且 all_time 应该为空,因为它显示了导致他们的购买总数第一次购买。
猜你喜欢
  • 2021-11-11
  • 1970-01-01
  • 2015-11-27
  • 2017-06-04
  • 1970-01-01
  • 1970-01-01
  • 2011-08-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多