我有一个名为“ Stack”的表。
Foo
我想找出Stack_Counter'20'中的堆栈数组。
所以正确答案应该是
+---------------+-------+-------------+
| Stack_Counter | value | Stack_Depth |
+---------------+-------+-------------+
| 1 | 3 | 1 |
| 2 | 0 | 2 |
| 3 | 0 | 1 |
| 4 | | 0 |
| 5 | 3 | 1 |
| 6 | 3 | 2 |
| 7 | 1 | 3 |
| 8 | 2 | 2 |
| 9 | 4 | 1 |
| 10 | 2 | 2 |
| 11 | 0 | 3 |
| 12 | 0 | 2 |
| 13 | 0 | 1 |
| 14 | 2 | 2 |
| 15 | 2 | 3 |
| 16 | 1 | 4 |
| 17 | 1 | 3 |
| 18 | 2 | 2 |
| 19 | 1 | 3 |
| 20 | 0 | 4 |
+---------------+-------+-------------+
基本上,这是找出所选Stack_Depth中的连续行。
有什么办法可以实现?
答案 0 :(得分:1)
...这是通用的全SQL解决方案:
SELECT Stack_Counter, value, Stack_Depth
FROM
(SELECT *, RANK() OVER (
PARTITION BY Stack_Depth
ORDER BY Stack_Counter DESC) rank
FROM stack)
WHERE rank=1 AND Stack_Depth > 0;
答案 1 :(得分:0)
仅使用SQL的解决方案可能比其价值更大的麻烦(由于其复杂性或乏味性),但这是与SQLite一起使用的解决方案:
SELECT * FROM (SELECT * FROM stack WHERE Stack_Depth=1 ORDER BY Stack_Counter DESC LIMIT 1)
UNION ALL
SELECT * FROM (SELECT * FROM stack WHERE Stack_Depth=2 ORDER BY Stack_Counter DESC LIMIT 1)
UNION ALL
SELECT * FROM (SELECT * FROM stack WHERE Stack_Depth=3 ORDER BY Stack_Counter DESC LIMIT 1)
UNION ALL
SELECT * FROM (SELECT * FROM stack WHERE Stack_Depth=4 ORDER BY Stack_Counter DESC LIMIT 1);
答案 2 :(得分:-1)
在我自己的评论中,我在注释中提到的窗口函数比我想象的要困难得多。 Peak的答案是使用rank()窗口函数的优雅解决方案,这正是我最初想要的。同时,sqlite还支持recursive CTE(公用表表达式; WITH语句):
WITH RECURSIVE
latest (id, level) AS (
VALUES (20, (SELECT Stack_Depth FROM stack WHERE Stack_Counter = 20))
UNION ALL
SELECT (SELECT max(Stack_Counter)
FROM stack
WHERE Stack_Depth = level - 1
AND Stack_Counter <= 20),
level - 1
FROM latest
WHERE level - 1 > 0
)
SELECT stack.*
FROM stack INNER JOIN latest
ON stack.Stack_Counter = latest.id
ORDER BY stack.Stack_Counter
我必须在三个位置插入所需的堆栈级别,但是如果您从宿主语言中的准备好的语句调用此参数,则可以用命名的SQL参数替换所有这些位置。
如果您对选择特定的Stack_Counter值不感兴趣,而只是希望从整个表中获取结果,则将VALUES
子句替换为SELECT之类的
WITH RECURSIVE
latest (id, level) AS (
SELECT * FROM (SELECT Stack_Counter, Stack_Depth FROM stack ORDER BY Stack_Counter DESC LIMIT 1)
UNION ALL
SELECT (SELECT max(Stack_Counter)
FROM stack
WHERE Stack_Depth = level - 1),
level - 1
FROM latest
WHERE level - 1 > 0
)
SELECT stack.*
FROM stack INNER JOIN latest
ON stack.Stack_Counter = latest.id
ORDER BY stack.Stack_Counter