【问题标题】:how can HQL limit the number of records in every group?HQL如何限制每个组中的记录数?
【发布时间】:2013-10-21 16:05:21
【问题描述】:

场景如下:表record如下:

A | B | C

1 | 1 | 1
2 | 1 | 1
3 | 1 | 1
4 | 1 | 2
5 | 1 | 2
6 | 1 | 3

HQL 的结果:select * from record where B = 1 and C < 3 limit 2 将是:

A | B | C

1 | 1 | 1
2 | 1 | 1

但我想要的是:

A | B | C

1 | 1 | 1
2 | 1 | 1
4 | 1 | 2
5 | 1 | 2

即:限制每个条件下的记录数,不限制最终返回的记录数。

我真的需要这个在蜂巢中完成。谁能给我一个想法?非常感谢!

总结 这是解决此问题的好方法: http://ragrawal.wordpress.com/2011/11/18/extract-top-n-records-in-each-group-in-hadoophive/

【问题讨论】:

    标签: hql hive sql-limit


    【解决方案1】:

    您应该能够使用 UNION 查询来做到这一点。

    SELECT A,B,C FROM
    (
      SELECT A, B, C FROM record WHERE B = 1 limit 2
      UNION AL L
      SELECT A, B, C FROM record WHERE C < 3 limit 2
    )
    

    你没有说可以通过这两个条件的行应该如何出现;如果需要,可以将DISTINCT 添加到外部SELECT,或者您可能需要添加到WHERE 子句以处理重叠情况。

    (是的,ALL 中不应该有空格,但是过滤协议会拒绝,因为它看起来像 sql 注入)

    拍2

    基于 cmets,似乎最好使用分析功能来解决,因为目标是在 B=1 和 C

    SELECT S.A, S.B, S.C
    FROM
     (SELECT A, B, C, row_number() over (partition by B,C) as r FROM record where B=1 AND C < 3) S
    WHERE S.r < 3
    

    这将给出所需的结果。在这种情况下,因为 B=1,所以 partition by 子句中实际上不需要 B。但如果 B 或 C 的限制发生变化,则需要。此外,如果 B、C 或它们的值之间存在其他关系,可以使用ifcase 进行修改。例如,如果 C 可以为 0,但想将其与 C=1 分组,则可以这样做

    (partition by B, if (C < 2,0,1))
    

    【讨论】:

    • 也许我没有传达正确的意思。经过测试,我认为这不能达到我想要的效果。你说可以同时通过这两个条件的行应该如何出现,就像某种group by,在每个组中,应该限制最大记录数。在那个例子中,当 (b=1 and c=1) 时,最多应该有 2 条记录,这与 (b=1 and c=2) 相同
    • PS 如果我没有描述清楚,请参考stackoverflow.com/questions/10421807/…,这是MySQL中的解决方案,但我不知道该怎么做蜂巢中的东西。谢谢!
    • 我认为引用是一个不同的问题,它希望第 1 列中每个不同值的前 2 行;我刚刚发布了一个解决方案。
    • 这有点相同的问题。我只是打算在一个 hql 中为每个组获取前 n 条记录。
    猜你喜欢
    • 2015-07-26
    • 1970-01-01
    • 2015-11-05
    • 1970-01-01
    • 2021-08-07
    • 1970-01-01
    • 2018-05-04
    • 2021-04-19
    • 1970-01-01
    相关资源
    最近更新 更多