Sqlite 选择列具有公共值的第n个范围/行孤岛?
我需要为一个范围选择所有行,这些行在一列中有一个公共值 例如,从最后一行开始 我尝试选择_user_id==1的所有行,直到_user_id!=1号 在这种情况下,会导致选择行[4、5、6]Sqlite 选择列具有公共值的第n个范围/行孤岛?,sqlite,Sqlite,我需要为一个范围选择所有行,这些行在一列中有一个公共值 例如,从最后一行开始 我尝试选择_user_id==1的所有行,直到_user_id!=1号 在这种情况下,会导致选择行[4、5、6] +------------------------+ | _id _user_id amount | +------------------------+ | 1 1 777 | | 2 2 1 | | 3 2 1
+------------------------+
| _id _user_id amount |
+------------------------+
| 1 1 777 |
| 2 2 1 |
| 3 2 11 |
| 4 1 10 |
| 5 1 100 |
| 6 1 101 |
+------------------------+
/*Create the table*/
CREATE TABLE IF NOT EXISTS t1 (
_id INTEGER PRIMARY KEY AUTOINCREMENT,
_user_id INTEGER,
amount INTEGER);
/*Add the datas*/
INSERT INTO t1 VALUES(1, 1, 777);
INSERT INTO t1 VALUES(2, 2, 1);
INSERT INTO t1 VALUES(3, 2, 11);
INSERT INTO t1 VALUES(4, 1, 10);
INSERT INTO t1 VALUES(5, 1, 100);
INSERT INTO t1 VALUES(6, 1, 101);
/*Check the datas*/
SELECT * FROM t1;
1|1|777
2|2|1
3|2|11
4|1|10
5|1|100
6|1|101
在我的尝试中,我使用对_user_id的结果进行分组。这将给出最后一行的索引,其中包含唯一值,例如,按_user_id LIMIT 2从t1 group中选择_id;将产生:[6,3]
然后,我使用这两个值选择一个范围,其中极限1偏移量1是下限3,极限1是上限6
WITH test AS (
SELECT _id FROM t1 GROUP BY _user_id LIMIT 2
) SELECT * FROM t1 WHERE _id BETWEEN 1+ (
SELECT * FROM test LIMIT 1 OFFSET 1
) and (
SELECT * FROM test LIMIT 1
);
输出:
4|1|10
5|1|100
6|1|101
这在选择最后一个岛时似乎可以,但我真正需要的是选择第n个岛的方法
当提供参数n时,是否有一种方法可以生成能够生成类似这些输出的查询
谢谢 SQL表是无序的,因此搜索孤岛的唯一方法是搜索连续的_id值:
谢谢你提供这个!然而,我遇到了一些问题,如果我删除一行,它将停止在前一行,因为主键不再是连续的。有什么想法吗?——“发牢骚”——这不是最初的问题所要求的……非常抱歉没有在前面提到这一点。无论如何,我已经找到了一种解决方法,通过更好地管理我如何删除条目,并确保PK保持连续,尽管这在将来可能仍然是一个问题。但是非常感谢你的回答,它非常有帮助!更改PKs通常是一个更糟糕的主意。谢谢您更新您的答案。它工作得非常好!是的,我同意改变PKs,我现在把代码撕掉。
island (n=1):
4|1|10
5|1|100
6|1|101
island (n=2):
2|2|1
3|2|11
island (n=3):
1|1|777
WITH RECURSIVE t1_with_islands(_id, _user_id, amount, island_number) AS (
SELECT _id,
_user_id,
amount,
1
FROM t1
WHERE _id = (SELECT max(_id)
FROM t1)
UNION ALL
SELECT t1._id,
t1._user_id,
t1.amount,
CASE WHEN t1._user_id = t1_with_islands._user_id
THEN island_number
ELSE island_number + 1
END
FROM t1
JOIN t1_with_islands ON t1._id = (SELECT max(_id)
FROM t1
WHERE _id < t1_with_islands._id)
)
SELECT *
FROM t1_with_islands
ORDER BY _id;