Select 个相邻条目
Select neighboring entries
我有一个带有文字注释的 table。我的应用程序显示按 pinned_flag
然后 note_date
排序的条目:
id | note_text | note_date | pinned_flag
----------------------------------------
1 | note1 | 01/04/2021 | 1
----------------------------------------
3 | note2 | 01/02/2021 | 1
----------------------------------------
5 | note3 | 01/05/2021 | 0
----------------------------------------
4 | note4 | 01/03/2021 | 0
----------------------------------------
2 | note5 | 01/01/2021 | 0
----------------------------------------
我需要 select 在具有给定 ID 的记录下方 1 条记录和上方 1 条记录。
(对于条目 5,结果将是 3 和 4)我可以使用哪些查询来执行此操作?
如果您的 SQLite 版本是 3.25.0+,您可以使用 ROW_NUMBER()
window 函数:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (ORDER BY pinned_flag DESC, note_date DESC) rn
FROM tablename
)
SELECT id, note_text, note_date, pinned_flag
FROM cte
WHERE (SELECT rn FROM cte WHERE id = 5) IN (rn - 1, rn + 1);
如果您不能使用 window 函数,但您的 SQLite 版本是 3.15.0+,您可以使用 UNION ALL
和 Row Values:
WITH cte AS (SELECT * FROM tablename WHERE id = 5)
SELECT * FROM (
SELECT * FROM tablename
WHERE (pinned_flag, note_date) > (SELECT pinned_flag, note_date FROM cte)
ORDER BY pinned_flag, note_date LIMIT 1
)
UNION ALL
SELECT * FROM (
SELECT * FROM tablename
WHERE (pinned_flag, note_date) < (SELECT pinned_flag, note_date FROM cte)
ORDER BY pinned_flag DESC, note_date DESC LIMIT 1
);
对于以前的版本:
WITH cte AS (SELECT * FROM tablename WHERE id = 5)
SELECT * FROM (
SELECT * FROM tablename
WHERE pinned_flag > (SELECT pinned_flag FROM cte)
OR (pinned_flag = (SELECT pinned_flag FROM cte) AND note_date > (SELECT note_date FROM cte))
ORDER BY pinned_flag, note_date LIMIT 1
)
UNION ALL
SELECT * FROM (
SELECT * FROM tablename
WHERE pinned_flag < (SELECT pinned_flag FROM cte)
OR (pinned_flag = (SELECT pinned_flag FROM cte) AND note_date < (SELECT note_date FROM cte))
ORDER BY pinned_flag DESC, note_date DESC LIMIT 1
);
参见demo。
我有一个带有文字注释的 table。我的应用程序显示按 pinned_flag
然后 note_date
排序的条目:
id | note_text | note_date | pinned_flag
----------------------------------------
1 | note1 | 01/04/2021 | 1
----------------------------------------
3 | note2 | 01/02/2021 | 1
----------------------------------------
5 | note3 | 01/05/2021 | 0
----------------------------------------
4 | note4 | 01/03/2021 | 0
----------------------------------------
2 | note5 | 01/01/2021 | 0
----------------------------------------
我需要 select 在具有给定 ID 的记录下方 1 条记录和上方 1 条记录。 (对于条目 5,结果将是 3 和 4)我可以使用哪些查询来执行此操作?
如果您的 SQLite 版本是 3.25.0+,您可以使用 ROW_NUMBER()
window 函数:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (ORDER BY pinned_flag DESC, note_date DESC) rn
FROM tablename
)
SELECT id, note_text, note_date, pinned_flag
FROM cte
WHERE (SELECT rn FROM cte WHERE id = 5) IN (rn - 1, rn + 1);
如果您不能使用 window 函数,但您的 SQLite 版本是 3.15.0+,您可以使用 UNION ALL
和 Row Values:
WITH cte AS (SELECT * FROM tablename WHERE id = 5)
SELECT * FROM (
SELECT * FROM tablename
WHERE (pinned_flag, note_date) > (SELECT pinned_flag, note_date FROM cte)
ORDER BY pinned_flag, note_date LIMIT 1
)
UNION ALL
SELECT * FROM (
SELECT * FROM tablename
WHERE (pinned_flag, note_date) < (SELECT pinned_flag, note_date FROM cte)
ORDER BY pinned_flag DESC, note_date DESC LIMIT 1
);
对于以前的版本:
WITH cte AS (SELECT * FROM tablename WHERE id = 5)
SELECT * FROM (
SELECT * FROM tablename
WHERE pinned_flag > (SELECT pinned_flag FROM cte)
OR (pinned_flag = (SELECT pinned_flag FROM cte) AND note_date > (SELECT note_date FROM cte))
ORDER BY pinned_flag, note_date LIMIT 1
)
UNION ALL
SELECT * FROM (
SELECT * FROM tablename
WHERE pinned_flag < (SELECT pinned_flag FROM cte)
OR (pinned_flag = (SELECT pinned_flag FROM cte) AND note_date < (SELECT note_date FROM cte))
ORDER BY pinned_flag DESC, note_date DESC LIMIT 1
);
参见demo。