sql最早记录

6ojccjat  于 2021-06-27  发布在  Hive
关注(0)|答案(3)|浏览(255)

假设我有一个20列的订单表。我只对前4列感兴趣:id、department\u id、region\u id、datetime,其中id是客户id,datetime是客户下订单的时间。其他列对于产品详细信息(例如产品标识)更为具体,因此对于给定的订单,您可能有多行。我正在努力编写一个查询,以获得每个客户最早的部门和地区,因为同一个客户可以有多个部门id和地区id的组合。

SELECT a.*
FROM (
    SELECT id,
        department_id,
        region_id,
        min(DATETIME) AS ts
    FROM orders
    GROUP BY id,
        department_id,
        region_id
    ) a
INNER JOIN (
    SELECT id,
        min(DATETIME) AS ts
    FROM orders
    GROUP BY id
    ) b
    ON a.id = b.id
        AND a.ts = b.ts

这似乎是可行的,但它似乎不是很有效,写得不好。有没有更好的方法写这个?表本身相当大,所以这个查询很慢。

xxslljrj

xxslljrj1#

我只想做:

SELECT id, department_id, region_id, datetime
FROM (SELECT o.*
             row_number() over (partition by id order by datetime) as seqnum
      FROM orders o
     ) o
where seqnum = 1;

编辑:
您可以在中试用此版本,看看是否效果更好:

select o.*
from orders o join
     (select id, min(datetime) as min_datetime
      from orders
      group by id
     ) oo
     on oo.id = o.id and oo.datetime = o.datetime;

在大多数数据库中 row_number() 版本可能会有更好的性能。然而,Hive可以做出神秘的优化决策,这可能会更好。

jrcvhitl

jrcvhitl2#

使用 dense_rank() 分析函数:

SELECT 
        id,
        department_id,
        region_id,
        min(DATETIME) AS ts
 FROM
(
SELECT  id,
        department_id,
        region_id,
        DATETIME,
        dense_rank() over(partition by id order by DATETIME) AS rnk
  FROM orders
)s 
WHERE rnk=1 --records with minimal date by id
GROUP BY id,
         department_id,
         region_id;

此查询与您的查询相同,但该表将被扫描一次,而不使用join。

biswetbf

biswetbf3#

我想你可以这样做:

SELECT id, department_id, region_id, min(datetime) AS ts 
FROM orders 
GROUP BY id, department_id, region_id 
HAVING ts=min(datetime)

相关问题