【发布时间】:2021-03-09 17:33:51
【问题描述】:
以下 SQL 查询应该返回集合中的最大连续数字。
WITH RECURSIVE Mystery(X,Y) AS (SELECT A AS X, A AS Y FROM R)
UNION (SELECT m1.X, m2.Y
FROM Mystery m1, Mystery m2
WHERE m2.X = m1.Y + 1)
SELECT MAX(Y-X) + 1 FROM Mystery;
对集合{7, 9, 10, 14, 15, 16, 18} 的此查询返回3,因为{14 15 16} 是最长的连续数字链,并且该链中有三个数字。但是,当我尝试手动完成此操作时,我看不到它是如何得出该结果的。
例如,给定上面设置的数字,我可以创建两列:
| m1.x | m2.y |
|---|---|
| 7 | 7 |
| 9 | 9 |
| 10 | 10 |
| 14 | 14 |
| 15 | 15 |
| 16 | 16 |
| 18 | 18 |
如果我们正在处理行和列,而不是实际数据,据我所知WHERE m2.X = m1.Y + 1 从 Y 中的下一行获取值并将其放在 X 的当前行中,就像这样
| m1.X | m2.Y |
|---|---|
| 9 | 7 |
| 10 | 9 |
| 14 | 10 |
| 15 | 14 |
| 16 | 15 |
| 18 | 16 |
| 18 | Null? |
我不确定的主要部分是 SQL 递归实际发生的位置。根据Denis Lukichev,递归是R 部分——或者在这种情况下是RECURSIVE Mystery(X,Y)——并在表为空时停止。但如果上述情况属实,那桌子怎么会空着呢?
由于我不知道如何进行上述操作,让我尝试不同的方向。如果WHERE m2.X = m1.Y + 1实际上是一个比较,结果应该是:
| m1.X | m2.Y |
|---|---|
| 14 | 14 |
| 15 | 15 |
| 16 | 16 |
但在这一点上,它似乎应该继续递归,直到只剩下两行(没有其他可比较的)。如果它在这里停止以获得正确的 3 行计数 (2 + 1),那么实际上停止递归的是什么?
我了解到,对于上述示例,MAX(Y-X) + 1 有效地返回了实际的递归步骤数并加了 1。
但是,如果我有 7 个连续的数字并且递归向下流动到 2 行,那么结果不应该是不正确的 3 吗?我了解 C++ 和其他语言中的递归,但这让我感到困惑。
完全公开,是的,这似乎是一个常见的大学问题,但我退休了,在研究递归供我使用时发现了这一点,并且需要了解在我的项目中使用类似递归的工作原理。
【问题讨论】:
-
我很好奇这里使用的 SQL 的确切版本。也许您可以将我们指向一个有效的 SQL Fiddle,然后我们可以解释结果。
-
您使用的是哪个 dbms?这在 mysql、sqlserver 或 oracle 中不起作用。
-
我使用 Postgres 为此创建了一个 similar DB Fiddle。这是否足够相似以至于您想要解释结果? dbfiddle.uk/…
-
我所见过的示例都没有指定哪个 dbm。我也无法让它在 MS SQL 或 MySQL 中工作。
-
如果没有人先到,我明天去看看