【问题标题】:Find TOP 10 latest record for each BUYER_ID for yesterday's date查找昨天日期的每个 BUYER_ID 的 TOP 10 最新记录
【发布时间】:2012-07-09 11:09:42
【问题描述】:

这是下表

CREATE TABLE IF NOT EXISTS TestingTable1 
( 
BUYER_ID BIGINT,
ITEM_ID BIGINT, 
CREATED_TIME STRING
)

这是上表中的以下数据-

BUYER_ID    |    ITEM_ID       |    CREATED_TIME
------------+------------------+-----------------------
1015826235      220003038067        2012-07-09 19:40:21,
1015826235      300003861266        2012-07-09 18:19:59,
1015826235      140002997245        2012-07-09 09:23:17,
1015826235      210002448035        2012-07-09 22:21:11,
1015826235      260003553381        2012-07-09 07:09:56,
1015826235      260003553382        2012-07-09 19:40:39,
1015826235      260003553383        2012-07-09 06:58:47,
1015826235      260003553384        2012-07-09 07:28:47,
1015826235      260003553385        2012-07-09 08:48:47,
1015826235      260003553386        2012-07-09 06:38:47,
1015826235      260003553387        2012-07-09 05:38:47,
1015826235      260003553388        2012-07-09 04:55:47,
1015826235      260003553389        2012-07-09 06:54:37,
34512201        597245693           2012-07-09 16:20:21,
34512201        8071787728          2012-07-09 15:19:59,
34512201        5868222883          2012-07-09 08:23:17,
34512201        2412180494          2012-07-09 22:21:11,
34512201        2422054205          2012-07-09 06:09:56,
34512201        1875744030          2012-07-09 19:40:39,
34512201        5639158173          2012-07-09 06:58:47,
34512201        5656232360          2012-07-09 07:28:47, 
34512201        959188449           2012-07-09 08:48:47,
34512201        4645350592          2012-07-09 06:38:47,
34512201        5657320532          2012-07-09 05:38:47,
34512201        290419656539        2012-07-09 04:55:47,

如果您在表中看到上述数据,则只有两个 UNIQUE BUYER_ID 并且对应于我拥有的 ITEM_ID AND CREATED_TIME。每当我为每个BUYER_ID 触发此查询(即昨天的日期)时,我只需要今天日期前一天的时间的 10 条最新记录。

因此,对于这个BUYER_ID - 34512201,我需要在 CREATED_TIME 的基础上为每个 BUYER_ID 提供 10 条最新记录,仅限昨天的日期。

每个BUYER_ID 可以有任何一天的数据。但我对今天的数据(总是指昨天的日期)特别感兴趣,请查看CREATED_TIME

为每个 BUYER_ID 查找昨天日期的 TOP 10 最新数据。下面是我应该得到的与每个 BUYER_ID 相对应的示例输出。

样本输出。

BUYER_ID    |    ITEM_ID       |    CREATED_TIME
------------+------------------+-----------------------
34512201        2412180494          2012-07-09 22:21:11
34512201        1875744030          2012-07-09 19:40:39
34512201        597245693           2012-07-09 16:20:21
34512201        8071787728          2012-07-09 15:19:59
34512201        959188449           2012-07-09 08:48:47
34512201        5868222883          2012-07-09 08:23:17
34512201        5656232360          2012-07-09 07:28:47 
34512201        5639158173          2012-07-09 06:58:47
34512201        4645350592          2012-07-09 06:38:47
34512201        2422054205          2012-07-09 06:09:56
1015826235      210002448035        2012-07-09 22:21:11
1015826235      260003553382        2012-07-09 19:40:39
1015826235      220003038067        2012-07-09 19:40:21
1015826235      300003861266        2012-07-09 18:19:59
1015826235      140002997245        2012-07-09 09:23:17
1015826235      260003553385        2012-07-09 08:48:47
1015826235      260003553384        2012-07-09 07:28:47
1015826235      260003553381        2012-07-09 07:09:56
1015826235      260003553383        2012-07-09 06:58:47
1015826235      260003553389        2012-07-09 06:54:37

我正在使用HiveHive 支持类似SQL 的语法。所以我需要确保 SQL 也应该在 Hive 环境中工作。

谁能帮我解决这个问题?

更新:-

我正在使用以下查询,我需要从以下查询中获取最新的前 10 名,并且需要再添加一个限定符以进行日期检查,这意味着在 where clause for yesterday's date- 我不能在这里使用 TOP 10,因为 Hive 没有支持TOP 10 sql 语法。我需要其他方法来解决这个问题。

SELECT * FROM TestingTable1 WHERE ORDER BY buyer_id, created_time DESC;

另一个更新:-

我使用RANK UserDefinedFunction 编写了以下查询。

SELECT buyer_id, item_id, created_time, rk
FROM (
    SELECT buyer_id, item_id, rank(item_id) as rk, created_time
    FROM testingtable1
    DISTRIBUTE BY buyer_id, item_id
    SORT BY buyer_id, item_id, created_time desc
) a 
WHERE rk < 10
ORDER BY buyer_id, created_time, rk;

这是 Java 中的 RANK UDF 函数-

package com.example.hive.udf;
import org.apache.hadoop.hive.ql.exec.UDF;

    public final class Rank extends UDF{
        private int  counter;
        private String last_key;
        public int evaluate(final String key){
          if ( !key.equalsIgnoreCase(this.last_key) ) {
             this.counter = 0;
             this.last_key = key;
          }
          return this.counter++;
        }
    }

上面的查询不是我想的那样工作,我猜在那个查询中必须做出某种扭曲。

有什么方法可以在不使用 HiveQL 中的任何 UDF 的情况下做到这一点?

【问题讨论】:

  • 您应该具体说明您使用的是哪种 SQL 语言。
  • 我正在使用 Hive 并且 Hive 支持 SQL Like 语法,所以这就是我将此问题标记为 SQL 的原因。我认为 oracle 语法在这里可以正常工作。
  • @Bohemian,知道如何做到这一点吗?
  • 我不知道 Rank 函数在这个 DBMS 中是如何工作的,但是 DISTRIBUTE BY 子句在 SQL Server 中看起来像 PARTITION BY,所以我猜你需要删除 item_id 列从那个子句。
  • RANK 不是函数,它是我创建的 UDF,您可以看到我刚刚在问题中所做的编辑。通过看问题,你就会明白我在说什么。你能提供我刚才对我说的确切查询吗?这样我会更了解。

标签: sql group-by sql-order-by hive hiveql


【解决方案1】:
  SELECT FIRST 10 *
    FROM TestingTable1
   WHERE buyer_id = 34512201
ORDER BY created_time DESC;

【讨论】:

  • 感谢 Frank 发表评论。我并不特定于buyer_id。可以有很多。而且我不需要前 10 个。我需要那一天的最新。按最新方式,该特定 BUYER_ID 按 desc 顺序持续 10 次
  • 既然你给出了那个例子,我就用它来做我的例子:) .. 好吧,通过在 DESCending 中对 created_time 进行排序,前 10 行将是最新的 10 行? ..ahh,为什么 created_time 没有定义为 DATETIME 数据类型?.. 如果您想要前几天的结果,您可以在 WHERE 子句中添加一个限定符。
  • 我不知道为什么他们没有定义为DATETIME 数据类型。我正在为其他人设计。他们已将其定义为字符串。所以我猜我必须使用它。我还发布了示例输出。
  • 然后您可以将该字符串转换为 DATETIME。 STRING 采用正确的 DATETIME YEAR TO SECOND 格式!
  • 我怎样才能为所有BUYER_ID 启用它,因为目前它只启用了一个。你能给我提供一个可以在我的场景中工作的例子吗?这对我会有很大帮助。并且FIRST 10.* 不适用于 Hive,因为我在 Hive 中工作并且 Hive 支持类似 SQL 的语法。
【解决方案2】:

我迟到了,我相信你一定知道在 Hive 中使用 row_number 函数。只是作为对先前良好讨论的参考的补充。

select * from
(select buyer_id,item_id,created_time, row_number() over(partition by buyer_id over
created_time asc) row_num from yourtable)tab
where tab.row_num<=5;

【讨论】:

    【解决方案3】:
    select * 
    from (select buyer_id,item_id,created_time,row_num() over (partition by buyer_id order by created_time DESC)) a 
    where a.row_num<=10
    

    【讨论】:

    • 请在您的回答中添加一些评论。 为什么这会起作用,它与其他答案有何不同。另外,也许你没有意识到,但这个问题已经有 7 年历史了。
    猜你喜欢
    • 1970-01-01
    • 2020-08-03
    • 2017-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-05
    相关资源
    最近更新 更多