我想在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”中的绝对最后一行加入。也就是说,我只知道最后一项已批准/未批准的状态。
非常感谢您的帮助!
答案 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;