mysql 如何获取BigQuery中的最新行

bksxznpy  于 12个月前  发布在  Mysql
关注(0)|答案(3)|浏览(119)

在BigQuery中,如何根据时间戳字段的最新值获取行?
例如,我有这张table。
| 名字|姓氏(_N)|使用自动(_A)|登录位置(_A)|
| --|--|--|--|
| 詹姆斯|戴维斯|真正|世界协调时2021年5月13日02:00:00|
| 詹姆斯|摩尔|真正|世界协调时2021年5月13日02时00分01秒|
| 詹姆斯|绿色|真正|世界协调时2021年5月13日02时00分02秒|
| 爱德华|绿色|虚假|世界协调时2021年5月13日03:00:00|
| 爱德华|威尔逊|虚假|世界协调时2021年5月13日03时00分01秒|
| 詹姆斯|戴维斯|虚假|世界协调时2021年5月13日03:00:00|
| 詹姆斯|摩尔|虚假|世界协调时2021年5月13日03时00分01秒|
| 詹姆斯|绿色|虚假|世界协调时2021年5月13日03时00分02秒|
| 爱德华|绿色|真正|世界协调时2021年5月13日02:00:00|
| 爱德华|威尔逊|真正|世界协调时2021年5月13日02:00:00|
我想在这样的查询后得到结果,
| 名字|姓氏(_N)|使用自动(_A)|登录位置(_A)|
| --|--|--|--|
| 爱德华|绿色|虚假|世界协调时2021年5月13日03:00:00|
| 爱德华|威尔逊|虚假|世界协调时2021年5月13日03时00分01秒|
| 詹姆斯|戴维斯|虚假|世界协调时2021年5月13日03:00:00|
| 詹姆斯|摩尔|虚假|世界协调时2021年5月13日03时00分01秒|
| 詹姆斯|绿色|虚假|世界协调时2021年5月13日03时00分02秒|
请告诉我应该使用什么查询。

dw1jzc5e

dw1jzc5e1#

BigQuery中一个方便的方法是使用聚合:

select array_agg(t order by login_at desc)[ordinal(1)].*
from thistable t
group by first_name, last_name;

字符串

dhxwm5r4

dhxwm5r42#

继续Gordon的回答:添加limit 1以减少内存消耗并提高可伸缩性:

select array_agg(t order by login_at desc limit 1)[ordinal(1)].*
from thistable t
group by t.first_name, t.last_name;

字符串

z9ju0rcb

z9ju0rcb3#

不知道为什么下面的两个解决方案都不适合我,我最终使用了这样的窗口函数:

SELECT first_name,  last_name,  use_auto, login_at  
FROM (
  SELECT first_name, last_name, use_auto, login_at
  ROW_NUMBER() OVER (PARTITION BY first_name, last_name ORDER BY login_at DESC) AS rn
  FROM thistable
) t
WHERE rn = 1

字符串
或CTE变体:

WITH t AS (
  SELECT first_name, last_name, use_auto, login_at
  ROW_NUMBER() OVER (PARTITION BY first_name, last_name ORDER BY login_at DESC) AS rn
  FROM thistable
)
SELECT first_name,  last_name,  use_auto, login_at  
FROM t
WHERE rn = 1


其逻辑是:
1.创建行号,按我们想要分组的一个分区,在本例中:first_name和last_name
1.仅过滤第一行编号
这也适用于如果你需要2个最新的行每组,前3组或类似的东西

注意事项:通常在其他支持多列匹配(例如PostgreSQL)的数据库(NOT BIGQUERY)中,我会这样做(不要忘记为3组列创建索引):

SELECT *
FROM thistable
WHERE (first_name, last_name, login_at) IN (
  SELECT first_name, last_name, MAX(login_at)
  FROM thistable
  GROUP BY 1, 2
)

相关问题