【问题标题】:Get first and last records in a table获取表中的第一条和最后一条记录
【发布时间】:2016-12-14 02:35:00
【问题描述】:

我有不同 STime 和 ETime 的 Id1 和 Id2。对于每组 Id1 和 Id2,我倾向于获取第一条和最后一条记录(如输出所示)。 我尝试使用 Id1 和 Id2 对表进行分区,并使用以下命令按 asc 和 desc 顺序对其进行排序:

ROW_NUMBER() OVER(PARTITION BY B.HardwareId, A.TripId ORDER BY StartTime) AS first_record,
ROW_NUMBER() OVER(PARTITION BY B.HardwareId, A.TripId ORDER BY StopTime DESC) AS last_record

我没有得到预期的结果。

SELECT
    A.Id1 AS Id1,
    A.Id2 AS TriId2pId,
    STime,
    ETime,
    Latitude,
    Longitude

FROM
    Tr.T1 AS A
JOIN
    Tp.G2 AS B
ON
    A.STime < B.DateTime
    AND A.ETime >= B.DateTime
    AND A.Id1 = B.Id1
WHERE
  (A._PARTITIONTIME BETWEEN TIMESTAMP('2016-11-23')
    AND TIMESTAMP('2016-11-23')
    AND A.Id1 IN (976))
ORDER BY
   B.Id1,
   A.Id2,
   B.DateTime 



    Id1 Id2 STime               ETime               Latitude    Longitude
    976 715 2016-11-23 13:06:26 2016-11-23 13:23:30 26.2230015  -80.12314    
    976 715 2016-11-23 13:06:26 2016-11-23 13:23:30 26.2229767  -80.12326    
    976 715 2016-11-23 13:06:26 2016-11-23 13:23:30 26.2226944  -80.12344
    976 800 2016-11-23 13:06:26 2016-11-23 13:24:59 26.2251511  -80.11865    
    976 800 2016-11-23 13:06:26 2016-11-23 13:24:59 26.2251511  -80.11912    
    976 800 2016-11-23 13:06:26 2016-11-23 13:24:59 26.2250233  -80.11929    
    976 800 2016-11-23 13:06:26 2016-11-23 13:24:59 26.2245369  -80.11929        


    Id1 Id2 STime               ETime               Latitude    Longitude
    976 715 2016-11-23 13:06:26 2016-11-23 13:23:30 26.2230015  -80.12314
    976 715 2016-11-23 13:06:26 2016-11-23 13:23:30 26.2226944  -80.12344
    976 800 2016-11-23 13:06:26 2016-11-23 13:24:59 26.2251511  -80.11865
    976 800 2016-11-23 13:06:26 2016-11-23 13:24:59 26.2245369  -80.11929   

【问题讨论】:

  • 每个 ID 或整个输出的第一个和最后一个?
  • 我正在为每个 Id 尝试它
  • 什么是firstlast?它是基于哪个字段?
  • 我正在尝试检索每个 hardwareId 的第一条和最后一条记录。
  • 1)。 hardwareId 甚至不在您的输出中-您应该分别更正您的问题; 2) 你对 FIRST 和 LAST 记录的定义是什么?它是基于某个时间场的吗?还是别的什么?

标签: google-bigquery


【解决方案1】:

您最初问题中的查询与您以后的 cmets 不完全匹配,但下面仍应帮助您实现目标

试试

SELECT
   A.Id AS Id,
   StartTime,
   StopTime,
   Latitude,
   Longitude
FROM (
  SELECT
   A.Id AS Id,
   StartTime,
   StopTime,
   Latitude,
   Longitude,
   ROW_NUMBER() OVER(PARTITION BY id ORDER BY StartTime) AS first_record,
   ROW_NUMBER() OVER(PARTITION BY id ORDER BY StartTime DESC) AS last_record
  FROM
   Tb1.Ids  AS A
  JOIN
   Tb2.Points AS B
  ON
   A.StartTime <= B.DateTime
   AND A.StopTime >= B.DateTime
   AND A.HardwareId = B.HardwareId
  WHERE
   (A._PARTITIONTIME BETWEEN TIMESTAMP('2016-11-23')
    AND TIMESTAMP('2016-11-23'))
   AND A.Id IN (334)
)
WHERE first_record = 1 OR last_record = 1  

这里的想法是在内部查询中添加两个字段,从开始和结束对所有行进行编号

   ROW_NUMBER() OVER(PARTITION BY id ORDER BY StartTime ) AS first_record,
   ROW_NUMBER() OVER(PARTITION BY id ORDER BY StartTime DESC) AS last_record

and than 分别保留第一行和最后一行

WHERE first_record = 1 OR last_record = 1  

【讨论】:

  • 对不起,当我根据 Id1 和 Id2 对它进行分区时,我没有得到想要的结果。
  • 但您最初的问题只是 Id1 而不是两个 Id!两个 ID 不是你的新问题吗?我正要回答?
  • 您能否澄清一下,如果您只使用一个 ID 就可以就原始问题获得所需的输出?
  • 由于 Id1 的分区不起作用,我尝试在分区中添加 Id2。
  • 好的,我没有得到这个,但希望其他人能够提供帮助。请注意 - 完全改变您的问题并不是它在 SO 上的工作方式,尤其是在您已经接受原始版本之后!如果您有新问题 - 您应该提出新问题并坚持下去。但不要回到旧的并重新编写它,使旧的答案不再相关。如果您希望这里的人能帮助您,这只是我给您的建议。
猜你喜欢
  • 2019-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-01
  • 1970-01-01
  • 2016-04-05
  • 2017-05-08
  • 2016-03-28
相关资源
最近更新 更多