【问题标题】:Postgresql selecting window of rows based on conditionsPostgresql根据条件选择行窗口
【发布时间】:2017-12-14 21:52:46
【问题描述】:

我有一个包含不同汽车行程的汽车行程数据。相关列是

  1. id - varchar(32)
  2. 序列 - 整数 - 重置为 1 以进行新车旅行
  3. 时间戳 - 设备记录 GPS 数据的时间。它在下图中显示为日期,但假设为时间戳
  4. 纬度 - 数字
  5. 经度

我正在尝试找出特定起点和终点之间的汽车行程。如果我输入 origin 为 40.34、23.5 和 destination 为 40.75、23.9,那么输出将如第二张图片所示。

第一张图片包含 2 次汽车旅行,即 abc 和 def。 'abc' 发生在 12 月 18 日,而 'def' 发生在 12 月 15 日,因此 def 首先出现在输出中。输出表按时间戳列和序列列排序,并按 id 分组。输出还应包含起点和终点之间的中间点。

我不知道如何找到经过特定地点的首次旅行。

输入:

输出:

【问题讨论】:

    标签: sql postgresql


    【解决方案1】:

    假设您的car trip data 表名为trips

    WITH starts_and_ends AS (
        SELECT
            starts.id,
            starts.sequence AS start_sequence,
            ends.sequence AS end_sequence
        FROM
            trips AS starts
            JOIN trips AS ends
            ON (starts.id = ends.id AND starts.sequence < ends.sequence)
        WHERE
            starts.latitude = 40.34 AND
            starts.longitude = 23.50 AND
            ends.latitude = 40.75 AND
            ends.longitude = 23.90
    )
    SELECT
        trips.*
    FROM
        starts_and_ends,
        trips
    WHERE
        trips.id = starts_and_ends.id AND
        sequence BETWEEN starts_and_ends.start_sequence AND starts_and_ends.end_sequence
    ORDER BY
        trips.id,
        trips.sequence,
        trips.timestamp;
    

    WITH 查询中,我选择起点和终点ID 和序列号。然后将其与原始表格连接以显示旅行。

    输出:

    abc 2   2017-12-18 40.34    23.50
    abc 3   2017-12-18 40.56    23.80
    abc 4   2017-12-18 40.75    23.90
    def 2   2017-12-15 40.34    23.50
    def 3   2017-12-15 40.55    23.59
    def 4   2017-12-15 40.80    23.99
    def 5   2017-12-15 40.75    23.90
    

    【讨论】:

      【解决方案2】:

      试试row_number() over()

      SELECT
            *
      FROM (
            SELECT
                  t.*
                , ROW_NUMBER() OVER (PARTITION BY id ORDER BY sequence, timestamp) AS rn
            FROM yourtable t
            WHERE Latitude = 40.34
            AND Longitude = 23.5
            ) d
      WHERE rn = 1
      

      nb:不确定排序中是否需要时间戳,但也许可以用作 tie-beaker。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-21
        • 1970-01-01
        • 2020-01-24
        • 2013-07-05
        • 2019-01-15
        相关资源
        最近更新 更多