【问题标题】:SQL Retrieve latest value relative to a subsetSQL 检索相对于子集的最新值
【发布时间】:2021-01-06 13:56:46
【问题描述】:

我正在尝试运行一个 SQL 查询,以获取与子集相关的最新结果。

鉴于设备 1 已链接到设备 3,我希望查询将设备 1 的颜色显示为设备 3 的颜色,因为设备 1 已链接到设备 3,并且设备 3 的颜色最近已更改。

当前结果:

Device | Color
-------+---------
   1   |  red 
   2   |  blue 
   3   |  green

我想要什么:

Device | Color
-------+---------
   1   |  GREEN 
   2   |  blue 
   3   |  GREEN

设备表

account_id
----------
   1  
   2   
   3    

信标表

 account_id | Color  | Time 
 -----------+--------+--------
     1      | red    |  6:00
     2      | blue   |  7:00
     3      | red    |  8:00
     3      | green  | 10:00 

链接表

 account_id | Link
------------+--------
     1      |   3
     2      |   - 
     3      |   - 

这就是我现在正在做的事情,这会导致设备的最新颜色,但不是链接设备。

SELECT d.* , b.*
FROM Device d
JOIN Beacons b ON d.account_id = b.account_id  
JOIN (
    SELECT b.account_id, 
        MAX(b.timestamp) as max_date
    FROM Beacons b
    GROUP BY b.account_id) x ON x.account_id = d.account_id
    AND x.max_date = b.timestamp

【问题讨论】:

  • 您使用的是哪个 dbms?请标记它
  • 刚刚添加的Sqlite
  • 您只谈到了要被链接 id 覆盖的颜色,但是 timestamp 列或任何列呢?
  • 如果设备 3 链接到设备 5 并且最近更改了设备 5 的颜色怎么办?在这种情况下,您希望得到什么结果?
  • 如果设备 3 链接到设备 5,它应该显示设备 5 的颜色。但是,如果设备 1 未链接到设备 5,它仍应仅显示最新的颜色设备 3。

标签: sql sqlite join window-functions


【解决方案1】:

这应该可行:

SELECT
  account_id,
  color
FROM Device AS d
JOIN (
  SELECT 
    linked_id AS account_id,
    color,
    ROW_NUMBER() OVER (PARTITION BY linked_id ORDER BY Time DESC) AS row_number
  FROM Beacons AS b
  JOIN (
    SELECT 
      account_id AS linked_id,
      Link AS account_id 
    FROM Linked
    ) USING (account_id)
) USING (account_id) 
WHERE row_number = 1
;

这是Demo

【讨论】:

    【解决方案2】:

    加入表格,然后LEFT 再加入 1 个 Beacons 副本,以获得链接设备的潜在颜色。
    然后使用窗口函数FIRST_VALUE() 得到那个颜色:

    select distinct d.account_id, 
           first_value(coalesce(b2.Color, b.Color)) over (partition by d.account_id order by coalesce(b2.Time, b.Time) desc) Color
    from Device d
    inner join Beacons b on b.account_id = d.account_id
    inner join Link l on l.account_id = d.account_id
    left join Beacons b2 on b2.account_id = l.Link and b2.Time > b.Time 
    

    请注意,Time 列的格式必须为 hh:mm,因此具有可比性。

    请参阅demo
    结果:

    > account_id | Color
    > ---------: | :----
    >          1 | green
    >          2 | blue 
    >          3 | green
    

    【讨论】:

      【解决方案3】:

      如果我正确地遵循了这个逻辑,你想加入链接并在某些情况下使用link

      SELECT COALESCE(l.link, d.account_id) as device, b.color
      FROM Device d LEFT JOIN
           Links l
           ON d.account_id = l.account_id LEFT JOIN
           (SELECT b.*,
                   ROW_NUMBER() OVER (PARTITION BY b.account_id ORDER BY b.time DESC) as seqnum
            FROM beacons b
           ) b
           ON b.account_id = COALESCE(l.link, d.account_id);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多