【发布时间】:2023-03-21 20:29:02
【问题描述】:
我想知道哪些在 2020 年 6 月订购的客户也在 2021 年 6 月订购了。我的代码返回了正确的 DISTINCT 订单,但对于在任一年份下超过一个订单的客户,折扣销售不正确。例如,一位客户在 2020 年下了一个订单,在 2021 年下了四个订单,2020 年的折扣销售额是实际金额的 4 倍。 2021 年的四个订单有四行,一个 2020 年的订单针对每一行进行填充。我通过使用暴露了潜在问题的 ROW_NUMBER () 看到了这一点。我不能将 DISTINCT 与折扣销售一起使用,因为客户确实以相同的美元金额下了多个订单。如何使用 BQ 的标准 SQL 获得确切的折扣销售额?
SELECT
DISTINCT ly.cuid AS cuid,
COUNT(DISTINCT ly.order_id) OVER (PARTITION BY ly.cuid) AS ly_orders,
SUM(ly.discounted_sales) OVER (PARTITION BY ly.cuid) AS ly_demand,
COUNT(DISTINCT ty.order_id) OVER (PARTITION BY ty.cuid) AS ty_orders,
SUM(ty.discounted_sales) OVER (PARTITION BY ly.cuid) AS ty_demand
FROM table ly
LEFT JOIN table ty
ON ly.cuid = ty.cuid
WHERE ly.order_date BETWEEN '2020-06-01' AND '2020-06-30'
AND ty.order_date BETWEEN '2021-06-01'AND '2021-06-30'
AND ly.financial_status <> 'credit'
AND ty.financial_status <> 'credit'
AND ly.discounted_sales >0
AND ty.discounted_sales >0
AND ly.channel = 'b2b'
AND ty.channel = 'b2b'
ORDER BY ly.cuid asc
[结果]
cuid ly_orders ly_demand ty_orders ty_demand comments
D 1 22,466.40 4 154,596.24 ly is 4x actual
F 2 2,573.20 1 1,944.40 ty is 2x actual
G 1 32,134.40 4 1,632.00 ly is 4x actual
I 2 757.56 1 730.56 ty is 2x actual
J 2 54,859.00 2 23,822.32 both are 2x actual
这行得通:
WITH prior_period AS (
SELECT
DISTINCT cuid AS ly_cuid,
COUNT(DISTINCT order_id) OVER (PARTITION BY cuid) AS ly_orders,
SUM(discounted_sales) OVER (PARTITION BY cuid) AS ly_demand
FROM TABLE
WHERE EXTRACT (YEAR FROM order_date) = 2020 AND EXTRACT(MONTH FROM order_date) = 6
AND financial_status <> 'credit'
AND discounted_sales >0
AND channel = 'b2b'
GROUP BY cuid, order_id, discounted_sales
ORDER BY cuid asc),
this_period AS (
SELECT
DISTINCT cuid AS ty_cuid,
COUNT(DISTINCT order_id) OVER (PARTITION BY cuid) AS ty_orders,
SUM(discounted_sales) OVER (PARTITION BY cuid) AS ty_demand
FROM TABLE
WHERE EXTRACT (YEAR FROM order_date) = 2021 AND EXTRACT(MONTH FROM order_date) = 6
AND financial_status <> 'credit'
AND discounted_sales >0
AND channel = 'b2b'
GROUP BY cuid, order_id, discounted_sales
ORDER BY cuid asc)
SELECT *
FROM prior_period ly
JOIN this_period ty ON ly.ly_cuid = ty.ty_cuid
ORDER BY ly.ly_cuid
【问题讨论】:
-
这将有助于查看数据和预期结果。基本上,您需要先聚合 JOIN 的每一侧,然后加入聚合数据。否则,您的联接将导致您的
SUMs /COUNTs 受到另一个表中的行的影响。 -
谢谢你,乔恩。我会尽力做到这一点。几周前我刚刚学习了 SQL。我还不允许嵌入照片,当我粘贴结果时,你现在可以看到它是一团糟。
-
没错。在加入之前进行聚合。但是您遗漏了其他细节,例如,如果您使用
GROUP BY,则不需要DISTINCT。当您不想将组/分区分别聚合到一行时,窗口函数很好。如果您注意到我的解决方案,我会避免这种情况并使用GROUP BY。使用我的方法可以简化一些。 -
如果你能提供一些测试数据,那可能会有所帮助。当与窗口函数结合使用时,您对
GROUP BY的使用可能是错误的,或者至少部分是不必要的。
标签: sql google-bigquery case partition