sqlite中的左联接表按desc限制排序

时间:2019-08-15 08:20:30

标签: sql database sqlite join left-join

我想在sqlite中保留两个表的连接。简短摘要:

我有一个名为“ _Menu”的表,该表中的一个字段名为“ menu_id”,具有唯一编号。

另一个表称为“ _Approvals”。该表具有“已批准”或“未批准”项目的历史记录。该表还具有一个名为“ menu_id”的字段。

我想从“ _Approvals”中获取给定menu_id的最低行(如果有的话),并将两个表连接起来。

到目前为止,我有:

SELECT m.menu_id, m.p_id AS parent_id, m.name, m.url, a.status, a.auth
FROM _Menu AS m
LEFT JOIN (
SELECT * FROM _Approvals ORDER BY _Approvals.approval_id DESC LIMIT 1) as a
ON a.menu_id = m.menu_id
GROUP BY m.menu_id
ORDER BY m.menu_id

我的问题是仅将“ _Approvals”中的绝对最后一行加入。也就是说,我只知道最后一项已批准/未批准的状态。

非常感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

您要的是“ _ Approvals”中给定menu_id的最低行 ,而不是“ _ Approvals”中的最低行 代码。
一种执行所需操作的方法是在所加入的子查询中使用NOT EXISTS:

SELECT m.menu_id, m.p_id AS parent_id, m.name, m.url, a.status, a.auth
FROM _Menu AS m
LEFT JOIN (
  SELECT * FROM _Approvals t
  WHERE NOT EXISTS (
    SELECT 1 FROM _Approvals
    WHERE menu_id = t.menu_id AND approval_id > t.approval_id
  )
) AS a
ON a.menu_id = m.menu_id
GROUP BY m.menu_id
ORDER BY m.menu_id

使用CTE的另一种方法:

WITH cte AS (
  SELECT t.* FROM _Approvals t 
  INNER JOIN (
    SELECT menu_id, MAX(approval_id) 
    FROM _Approvals
    GROUP BY menu_id
  ) g
  ON g.menu_id = t.menu_id
)
SELECT m.menu_id, m.p_id AS parent_id, m.name, m.url, a.status, a.auth
FROM _Menu AS m LEFT JOIN cte AS a
ON a.menu_id = m.menu_id
GROUP BY m.menu_id
ORDER BY m.menu_id

或者如果您的 SQLite 版本为3.25.0+,则使用窗口功能ROW_NUMBER()

WITH cte AS (
  SELECT *,
    ROW_NUMBER() OVER (PARTITION BY menu_id ORDER BY approval_id DESC) rn
  FROM _Approvals 
)
SELECT m.menu_id, m.p_id AS parent_id, m.name, m.url, a.status, a.auth
FROM _Menu AS m LEFT JOIN (
  SELECT * FROM cte
  WHERE rn = 1
) AS a
ON a.menu_id = m.menu_id
GROUP BY m.menu_id
ORDER BY m.menu_id

答案 1 :(得分:1)

我建议使用row_number()编写此代码:

SELECT m.menu_id, m.p_id AS parent_id, m.name, m.url,
       a.status, a.auth
FROM _Menu m LEFT JOIN
     (SELECT a.*,
             ROW_NUMBER() OVER (PARTITION BY a.menu_id ORDER BY a.approval_id DESC) as seqnum
      FROM _Approvals a
     ) a
     ON a.menu_id = m.menu_id AND a.seqnum = 1
ORDER BY m.menu_id;

假设menu_id_Menu中的主键,则查询不需要聚合。

如果使用的是不支持窗口功能的旧版SQLite,则有多个选项。可能最简单的是:

SELECT m.menu_id, m.p_id AS parent_id, m.name, m.url,
       a.status, a.auth
FROM _Menu m LEFT JOIN
     _Approvals a
     ON a.menu_id = m.menu_id LEFT JOIN
     (SELECT a.menu_id, MAX(a.approval_id) as max_approval_id
      FROM _Approvals a
      GROUP BY a.menu_id
     ) aa
     ON aa.menu_id = a.menu_id AND
        aa.max_approval_id = a.approval_id
ORDER BY m.menu_id;