【问题标题】:SQL Total Distinct Count on Group By QuerySQL Total Distinct Count on Group By Query
【发布时间】:2020-01-03 21:57:58
【问题描述】:

尝试获取具有 group by 的一系列记录的员工总数。

我尝试过使用“over()”子句,但无法让它发挥作用。最好用一个例子来解释,所以请看下面我的脚本和下面想要的结果。

编辑: 我应该提一下,我希望有一个不使用基于下面我的“sales_detail”表的子查询的解决方案,因为在我的真实示例中,“sales_detail”表是一个非常复杂的子查询。

这是我想要的结果。 “wanted_result”列应为 9:

示例脚本:

CREATE TEMPORARY TABLE [sales_detail] (
    [employee] varchar(100),[customer] varchar(100),[startdate] varchar(100),[enddate] varchar(100),[saleday] int,[timeframe] varchar(100),[saleqty] numeric(18,4)
);

INSERT INTO [sales_detail]
    ([employee],[customer],[startdate],[enddate],[saleday],[timeframe],[saleqty])
VALUES
    ('Wendy','Chris','8/1/2019','8/12/2019','5','Afternoon','1'),
    ('Wendy','Chris','8/1/2019','8/12/2019','5','Morning','5'),
    ('Wendy','Chris','8/1/2019','8/12/2019','6','Morning','6'),
    ('Dexter','Chris','8/1/2019','8/12/2019','2','Mid','2.5'),
    ('Jennifer','Chris','8/1/2019','8/12/2019','4','Morning','2.75'),
    ('Lila','Chris','8/1/2019','8/12/2019','2','Morning','3.75'),
    ('Rita','Chris','8/1/2019','8/12/2019','2','Mid','1'),
    ('Tony','Chris','8/1/2019','8/12/2019','4','Mid','2'),
    ('Tony','Chris','8/1/2019','8/12/2019','1','Morning','6'),
    ('Mike','Chris','8/1/2019','8/12/2019','4','Mid','1.5'),
    ('Logan','Chris','8/1/2019','8/12/2019','3','Morning','6.25'),
    ('Blake','Chris','8/1/2019','8/12/2019','4','Afternoon','0.5')
;

  SELECT
    [timeframe],
    SUM([saleqty]) AS [total_qty],
    COUNT(DISTINCT [s].[employee]) AS [employee_count1],
    SUM(COUNT(DISTINCT [s].[employee])) OVER() AS [employee_count2],
    9 AS [wanted_result]
  FROM (
    SELECT 
        [employee],[customer],[startdate],[enddate],[saleday],[timeframe],[saleqty]
    FROM 
        [sales_detail]
  ) AS [s]
  GROUP BY
    [timeframe]
;

【问题讨论】:

  • 您标记了 postgresql,但语法看起来像 SQL Server。
  • 这是基于 Postgresql 的 Redshift
  • 我从未在 SQL Server 中见过CREATE TEMPORARY TABLE

标签: sql group-by count amazon-redshift distinct


【解决方案1】:

你可以试试下面这个选项-

SELECT
[timeframe],
SUM([saleqty]) AS [total_qty],
COUNT(DISTINCT [s].[employee]) AS [employee_count1],
SUM(COUNT(DISTINCT [s].[employee])) OVER() AS [employee_count2],
[wanted_result]
-- select count form sub query
FROM (
    SELECT 
    [employee],[customer],[startdate],[enddate],[saleday],[timeframe],[saleqty],
    (select COUNT(DISTINCT [employee]) from [sales_detail]) AS [wanted_result]
    --caculate the count with first sub query
    FROM [sales_detail]
) AS [s]
GROUP BY
[timeframe],[wanted_result]

【讨论】:

  • 感谢您的帮助,但我更愿意在我的“sales_detail”表上不使用子查询的解决方案,因为在我的实际项目中,它是一个复杂的子查询而不是一个简单的表。我这样做只是为了演示。
  • 如果使用 GROUP BY,则需要 JOIN 查询结果或使用子查询从整体数据中获取聚合结果。
【解决方案2】:

如果我理解正确,您只是在为表中的所有员工寻找COUNT(DISTINCT)?我相信这个查询会返回你正在寻找的结果:

SELECT
  [timeframe],
  SUM([saleqty]) AS [total_qty],
  COUNT(DISTINCT [s].[employee]) AS [employee_count1],
  (SELECT COUNT(DISTINCT [employee]) FROM [sales_detail]) AS [employee_count2],
  9 AS [wanted_result]
FROM #sales_detail [s]
GROUP BY
  [timeframe]

【讨论】:

  • 感谢您的帮助,但我更愿意在我的“sales_detail”表上不使用子查询的解决方案,因为在我的实际项目中,它是一个复杂的子查询而不是一个简单的表。我这样做只是为了演示。
【解决方案3】:

使用只在每个人出现的第一天计算每个人的技巧:

select timeframe, sum(saleqty) as total_qty),
       count(distinct employee) as employee_count1,
       sum( (seqnum = 1)::int ) as employee_count2
       9 as wanted_result
from (select sd.*,
             row_number() over (partition by employee order by startdate) as seqnum
      from sales_detail sd
     ) sd
group by timeframe;

注意:从性能的角度来看,您的复杂子查询只评估一次。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-07
    • 1970-01-01
    • 1970-01-01
    • 2020-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多