【问题标题】:Count Distinct Window Function with Groupby使用 Groupby 计数不同的窗口函数
【发布时间】:2021-08-26 21:07:21
【问题描述】:

我有一个包含用户名、市场和purchase_id 的表。我正在尝试在没有子查询的情况下在 SnowSql 中使用窗口函数来计算用户购买的不同购买次数以及市场上唯一购买的总数。

初始表

User Market Purchase_ID
John Smith NYC 1
John Smith NYC 2
Bob Miller NYC 2
Bob Miller NYC 4
Tim Wilson NYC 3

想要的结果如下所示:

User Purchases Unique Market Purchases
John Smith 2 4
Bob Miller 2 4
Tim Wilson 1 4

我一直在尝试的不带子查询的查询如下所示,但 groupby 收到错误。

SELECT 
  user,
  COUNT(DISTINCT purchase_id),
  COUNT(DISTINCT purchase_id) OVER (partition by market)
FROM table
GROUP BY 1

感谢您对此提供的任何帮助。谢谢!

【问题讨论】:

  • 你为什么不group by user,而不是1?
  • @JaimeDrq 相同的 1 代表第一列

标签: sql snowflake-cloud-data-platform window-functions


【解决方案1】:

这可能行得通,你可以争先恐后地进入你所追求的格式,但它会产生没有子查询的答案。

使用了很棒的GROUPING SETS,它允许在单个语句中使用多个 group-by 子句-您遇到的确切错误:-)。

很棒的问题!

  SELECT 
      COUNT(DISTINCT PURCHASE_ID)  
    , USER_NAME
    , MARKET
 FROM 
    CTE
  GROUP BY 
    GROUPING SETS (USER_NAME, MARKET);

复制|粘贴|运行

WITH CTE AS (SELECT 'JOHN SMITH' USER_NAME, 'NYC' MARKET,   1 
PURCHASE_ID
UNION SELECT 'JOHN SMITH' USER_NAME,    'NYC' MARKET,   2 PURCHASE_ID
UNION SELECT 'BOB MILLER' USER_NAME,    'NYC' MARKET,   2 PURCHASE_ID
UNION SELECT 'BOB MILLER' USER_NAME,    'NYC' MARKET,   4 PURCHASE_ID
UNION SELECT 'TIM WILSON' USER_NAME,    'NYC' MARKET,   3 PURCHASE_ID) 

SELECT 
      COUNT(DISTINCT PURCHASE_ID)  
    , USER_NAME
    , MARKET
FROM 
    CTE
GROUP BY 
    GROUPING SETS (USER_NAME, MARKET);

【讨论】:

  • 没有 MySQL 标签……它是雪花标签。为什么雪花题需要兼容 MySQL??
  • 对不起,它被重新标记了
  • 不客气...很高兴您花时间阅读所有其他答案!
【解决方案2】:

我认为您不能简单地作为聚合来做到这一点。但是你可以得到这样的答案:

SELECT user,
       SUM( (seqnum = 1)::INT ) as purchases,
       SUM(SUM( (seqnum = 1)::INT )) OVER (PARTITION BY market) as market_purchases
FROM (SELECT t.*,
             ROW_NUMBER() OVER (PARTITION BY purchase_id ORDER BY purchase_id) as seqnum
      FROM table t
     ) t
GROUP BY 1

【讨论】:

  • 有点违背要求:“我正在尝试在没有子查询的情况下在 SnowSql 中使用窗口函数”
  • 如您所见,窗口函数没有这种可能性
【解决方案3】:

DISTTNCT在窗口函数中是不允许的,所以你需要使用子查询

CREATE TABLE table1
    (`User` varchar(10), `Market` varchar(3), `Purchase_ID` int)
;
    
INSERT INTO table1
    (`User`, `Market`, `Purchase_ID`)
VALUES
    ('John Smith', 'NYC', 1),
    ('John Smith', 'NYC', 2),
    ('Bob Miller', 'NYC', 2),
    ('Bob Miller', 'NYC', 4),
    ('Tim Wilson', 'NYC', 3)
;
SELECT 
  user,
  COUNT(DISTINCT purchase_id)
  ,MAX((SELECT COUNT(DISTINCT purchase_id) FROM table1 WHERE `Market` = t1.`Market` )) bymarkte
FROM table1 t1
GROUP BY 1
用户 | COUNT(DISTINCT purchase_id) |由市场 :--------- | --------------------------: | --------: 鲍勃·米勒 | 2 | 4 约翰·史密斯 | 2 | 4 蒂姆·威尔逊 | 1 | 4
SELECT 
  user,
  COUNT(DISTINCT purchase_id)
  ,MAX(countr) bymarkte
FROM table1 t1
INNER JOIN (SELECT `Market`,COUNT(DISTINCT purchase_id) countr FROM table1 GROUP BY  `Market` ) ta ON t1.`Market` = ta.`Market`

GROUP BY 1
用户 | COUNT(DISTINCT purchase_id) |由市场 :--------- | --------------------------: | --------: 鲍勃·米勒 | 2 | 4 约翰·史密斯 | 2 | 4 蒂姆·威尔逊 | 1 | 4

db小提琴here

【讨论】:

  • MySQL 有分组汇总吗?这是解决这个问题的另一种方法
  • 但我看不出你将如何管理独特的
  • Roll ups 也可以在没有子查询的情况下解决……只是需要更多的争论才能得到他想要的输出。
  • 是的,但是 urser 想要一个带有窗口功能的“简单”解决方案,我认为这种情况不会很快发生
猜你喜欢
  • 2020-02-09
  • 2016-10-23
  • 2012-11-08
  • 1970-01-01
  • 2021-06-26
  • 1970-01-01
  • 2021-03-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多