链表:查询存储在sql表中的链表的第一个和最后一个元素

bn31dyow  于 2021-07-29  发布在  Java
关注(0)|答案(3)|浏览(574)

我有一个sql表,其中的“行”表示链表的元素。例如,我可以有以下记录:

  1. (id, previous_id)
  2. ------------------
  3. (1, NULL)
  4. (2, NULL)
  5. (3, 2)
  6. (4, 3)
  7. (5, NULL)
  8. (6, 4)
  9. (7, 5)

此表中有3个列表:

  1. (1,)
  2. (2,3,4,6)
  3. (5,7)

我想找出每个列表的最后一个元素和列表中的元素数。我要查找的查询将输出:

  1. last, len
  2. 1, 1
  3. 6, 4
  4. 7, 2

这在sql中可能吗?

slmsl1lt

slmsl1lt1#

  1. WITH RECURSIVE cte AS (
  2. SELECT id AS first, id AS last, 1 as len
  3. FROM lines
  4. WHERE previous_id IS NULL
  5. UNION ALL
  6. SELECT c.first, l.id, len + 1
  7. FROM cte c
  8. JOIN lines l ON l.previous_id = c.last
  9. )
  10. SELECT DISTINCT ON (first)
  11. last, len -- , first -- also?
  12. FROM cte
  13. ORDER BY first, len DESC;

db<>在这里摆弄
精确生成结果。
如果你还想要第一个元素,比如你的标题状态,那是很容易得到的。

展开查看全部
pgpifvop

pgpifvop2#

可以使用递归cte:

  1. with recursive cte as (
  2. select l.previous_id as id, id as last
  3. from lines l
  4. where not exists (select 1 from lines l2 where l2.previous_id = l.id)
  5. union all
  6. select l.previous_id, cte.last
  7. from cte join
  8. lines l
  9. on cte.id = l.id
  10. )
  11. select cte.last, count(*)
  12. from cte
  13. group by cte.last;

这是一把小提琴。

xkrw2x1b

xkrw2x1b3#

下面是microsoft sql server 2016 db中的一个实现

  1. WITH chain
  2. AS (SELECT l.id AS [first],
  3. l.id AS [last],
  4. 1 AS [len]
  5. FROM lines AS l
  6. WHERE l.previous_id IS NULL
  7. UNION ALL
  8. SELECT c.[first],
  9. l.id,
  10. c.[len] + 1 AS [len]
  11. FROM chain AS c
  12. JOIN lines AS l ON l.previous_id = c.[last]),
  13. result
  14. AS (SELECT DISTINCT
  15. c.[first],
  16. c.[last],
  17. c.[len],
  18. ROW_NUMBER() OVER(PARTITION BY c.[first] ORDER BY c.[len] DESC) AS rn
  19. FROM chain as c)
  20. SELECT r.[first],
  21. r.[last],
  22. r.[len]
  23. FROM result AS r
  24. WHERE r.rn = 1
  25. ORDER BY r.[first];
展开查看全部

相关问题