【问题标题】:counting by cases over grouped time在分组时间内按病例计数
【发布时间】:2016-10-17 17:17:26
【问题描述】:

我正在尝试按版本类型计算每周出现在我的数据中的不同 ID,但我不确定如何正确构建查询。

我希望按照以下方式制作一个表格:

      1.1     1.2     1.3    1.4
wk1     1       5       4      8
wk2     4       3       9      8
wk3     1       8       0      6

我尝试制作下面的查询,但它不会运行,因为它需要 group by 中的 Case 语句,然后它不会接受 count()。

  SELECT
  Case  when version like "1.1%" then Count(distinct ID)
     when version like "1.2%" then Count(distinct ID)
     when version like "1.3%" then Count(distinct ID)
     when version like "1.4%" then Count(distinct ID) end,
  CAST(((datediff(timestamp_pst,'2016-01-03') / 7)+1) as INT) as week_of_the_year
  FROM db.table
  where timestamp_pst >=  "2016-01-28"
  group by CAST(((datediff(timestamp_pst,'2016-01-03') / 7)+1) as INT)  
        order by week_of_the_year

【问题讨论】:

  • 你不想要像SUM( CASE WHEN ... THEN 1 ELSE 0 END) x... 这样的东西吗(虽然我会在应用程序代码中处理这种事情)
  • @Strawberry - 即使列列表已修复,也会在应用端执行此操作?
  • @Strawberry 如果 ID 重复要建议的接缝 COUNT(DISTINCT) 将不会产生与 SUM(CASE WHEN THEN 1 ELSE 0 END) 相同的结果,后者将等效于 COUNT() 其中版本如....

标签: sql count group-by hive case


【解决方案1】:
  SELECT
    COUNT(DISTINCT (CASE WHEN version like '1.1%' THEN ID END)) as '1.1'
    ,COUNT(DISTINCT (CASE WHEN version like '1.2%' THEN ID END)) as '1.2'
    ,COUNT(DISTINCT (CASE WHEN version like '1.3%' THEN ID END)) as '1.3'
    ,COUNT(DISTINCT (CASE WHEN version like '1.4%' THEN ID END)) as '1.4'
  CAST(((datediff(timestamp_pst,'2016-01-03') / 7)+1) as INT) as week_of_the_year
  FROM aws_d3.iaanalytics_detail
  where timestamp_pst >=  "2016-01-28"
  group by CAST(((datediff(timestamp_pst,'2016-01-03') / 7)+1) as INT)  
        order by week_of_the_year

您想要使用“条件聚合”。这样做,case 语句实际上进入了聚合函数内部。因为您想要COUNT(DISTINCT),您实际上需要通过在聚合中使用DISTINCT 关键字或通过制作派生表来做到这一点,因此只有不同的值出现,正如另一个答案所暗示的那样,但作为唯一的词它会避免重复是DISTINCT 我认为没有必要使用派生表使事情复杂化。

请注意,SUM(CASE WHEN blah THEN 1 ELSE 0 END)为您工作,因为它会将所有出现的次数相加而不计算不同的值。此外,聚合函数会忽略空值,并且当您不包含 ELSE 语句时,如果不匹配,则 case 表达式 的值将为 NULL

【讨论】:

  • 这很好用,我在 Hive 工作,它不喜欢 '1.1' 但除此之外它很完美。
【解决方案2】:

您可以将COUNT() 聚合函数与条件CASE 语句一起使用。

SELECT
    week_of_the_year
  , COUNT(CASE WHEN version LIKE '1.1%' THEN id END) AS v1_1
  , COUNT(CASE WHEN version LIKE '1.2%' THEN id END) AS v1_2
  , COUNT(CASE WHEN version LIKE '1.3%' THEN id END) AS v1_3
  , COUNT(CASE WHEN version LIKE '1.4%' THEN id END) AS v1_4
FROM (
  SELECT
    DISTINCT
      id
    , version
    , CAST(((datediff(timestamp_pst,'2016-01-03') / 7)+1) as INT) as week_of_the_year
  FROM aws_d3.iaanalytics_detail
  where timestamp_pst >= '2016-01-28'
  ) t
GROUP BY week_of_the_year
ORDER BY week_of_the_year

请注意,查询的DISTINCT 部分发生在派生表t 中。实际上不需要派生表,但我发现它是一个更简洁的解决方案,因为GROUP BY 子句不会重复相同的代码并使其更具可读性。这也引入了不能在聚合中完成的不同部分。

【讨论】:

    【解决方案3】:

    试试这个

    SELECT
      SUM(Case  when version like "1.1%" then 1 ELSE 0 END) as '1.1',
      SUM(Case  when version like "1.2%" then 1 ELSE 0 END) as '1.2',
      SUM(Case  when version like "1.3%" then 1 ELSE 0 END) as '1.3', 
      SUM(Case  when version like "1.4%" then 1 ELSE 0 END) as '1.4',
      CAST(((datediff(timestamp_pst,'2016-01-03') / 7)+1) as INT) as week_of_the_year
      FROM aws_d3.iaanalytics_detail
      where timestamp_pst >=  "2016-01-28"
      group by CAST(((datediff(timestamp_pst,'2016-01-03') / 7)+1) as INT)  
            order by week_of_the_year
    

    【讨论】:

    • 如果 ID 可以按照 COUNT(DISTINCT) 的建议重复,这将不起作用
    猜你喜欢
    • 2020-10-07
    • 2021-08-27
    • 2020-03-09
    • 2014-12-19
    • 1970-01-01
    • 2018-04-10
    • 1970-01-01
    • 2013-11-24
    • 1970-01-01
    相关资源
    最近更新 更多