【问题标题】:How to filter data based on count without hitting the sub-table/sub-query twice?如何根据计数过滤数据而不点击两次子表/子查询?
【发布时间】:2019-10-19 02:44:58
【问题描述】:

我有以下数据,我想通过在 cd 列上应用计数来过滤掉这些数据(即获取所有列,例如 count(cd) > 3)

数据样本(通过子查询导出)

cd  c1  c2  d1
----------------
aa  23  681 4850
aa  23  942 4850
aa  28  944 4881
aa  28  221 4850
bb  46  443 9082
cc  77  171 2831
cc  77  272 2831
dd  18  798 5993
xx  71  166 8755
xx  71  482 3818
xx  71  565 7598
xx  71  603 7246
xx  71  649 4293
xx  71  681 7321
xx  71  250 7453
xx  22  276 3818
xx  22  107 8755
yy  28  143 5802
zz  33  624 3205
zz  33  767 1532
zz  33  372 3205
zz  33  679 3838

我正在使用以下查询,但我不想点击 test_data,因为 hive 表中的数据量很大。 (注意:这里的 test_data 是从同一个查询中的其他子查询派生而来的)

SELECT cd, c1, c2, d1 
FROM test_data
WHERE cd IN (SELECT cd FROM test_data group by cd having count(cd) > 3)

【问题讨论】:

    标签: sql apache-spark hive hiveql


    【解决方案1】:

    您可以使用窗口函数来获取每个 cd 组的计数,但实际上并不聚合,然后过滤掉计数低于 4 的行。虽然这仍然需要子查询,但您没有加入任何表,所以它的性能应该更高一些。

    SELECT 
    cd, 
    c1, 
    c2, 
    d1 
    FROM (
      SELECT
      cd, 
      c1, 
      c2, 
      d1,
      count(1) OVER (PARTITION BY cd ORDER BY c1 DESC) as cd_count 
      FROM test_data
    ) test_data_1
    WHERE cd_count > 3;
    

    【讨论】:

    • 感谢您的回答,但我想要 cd_count > 3,这将错过前两条记录
    【解决方案2】:

    使用窗口函数获取 cd 的计数,然后使用 where 子句过滤数据,如下查询

    select * from (Select cd,c1,c2,d1 , count(cd) OVER (PARTITION BY cd) as cnt FROM test_data) a where cnt> 3

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多