【问题标题】:Query with WITH clause and COUNT subquery使用 WITH 子句和 COUNT 子查询进行查询
【发布时间】:2020-02-13 16:30:18
【问题描述】:

在下面的查询中,我没有得到预期的结果。任何见解为什么?我怎样才能重新制定这样的查询以获得所需的结果?

架构 (SQLite v3.30)

WITH RECURSIVE
  cnt(x,y) AS (VALUES(0,ABS(Random()%3)) UNION ALL SELECT x+1, ABS(Random()%3) FROM cnt WHERE x<10),
  i_rnd as (SELECT r1.x, r1.y, (SELECT COUNT(*) FROM cnt as r2 WHERE r2.y<=r1.y) as idx FROM cnt as r1)
SELECT * FROM i_rnd ORDER BY y;

结果:

| x   | y   | idx |
| --- | --- | --- |
| 1   | 0   | 3   |
| 5   | 0   | 6   |
| 8   | 0   | 5   |
| 9   | 0   | 4   |
| 10  | 0   | 2   |
| 3   | 1   | 4   |
| 0   | 2   | 11  |
| 2   | 2   | 11  |
| 4   | 2   | 11  |
| 6   | 2   | 11  |
| 7   | 2   | 11  |

预期结果:

| x   | y   | idx |
| --- | --- | --- |
| 1   | 0   | 5   |
| 5   | 0   | 5   |
| 8   | 0   | 5   |
| 9   | 0   | 5   |
| 10  | 0   | 5   |
| 3   | 1   | 6   |
| 0   | 2   | 11  |
| 2   | 2   | 11  |
| 4   | 2   | 11  |
| 6   | 2   | 11  |
| 7   | 2   | 11  |

换句话说,idx 应该指示有多少行 y 小于或等于所考虑的行的 y。

【问题讨论】:

    标签: sql sqlite count


    【解决方案1】:

    我只会使用:

    select cnt.*,
           count(*) over (order by y)
    from cnt;
    

    Here 是一个 dbfiddle。

    您的代码的问题可能是每次调用 CTE 时都会重新评估它,因此值不一致 - CTE 中的 volatile 函数存在问题。

    【讨论】:

    • 天才!肯定必须是对CTE的重新评估。感谢您的建议,我现在可以在 N 个数字上生成一个带有“假”rowid 的随机序列,以用于更新查询:WITH RECURSIVE cnt (x,y) AS ( select 0, Random() UNION ALL SELECT x+1, Random() FROM cnt WHERE x&lt;10), p as (select cnt.*, count(*) over (order by y,x) from cnt) select * from p; 其中order by y,x 中的 x 解决了随机重复的罕见情况下的歧义
    • 哦,虽然它不适用于 3.25 版之前的 sqlite,所以它不适用于 android...这就是为什么我没有使用最简单的 ROW_NUMBER 来达到我的目的...
    • 您对 3.25 之前的解决方案有什么建议吗?
    • @AndrewBloom。 . .这个问题是关于支持窗口函数的 SQLite 版本的明确说明。这在早期版本中可能要复杂得多。我会建议一个临时表。
    • 我的错,我尝试使用 dbfiddle 进行查询,其中没有 db pre 3.25 并且误导性 Schema (SQLite v3.30) 来自那里。我想如果我必须修改这个问题,但你的答案是正确的,所以我会保持原样。我实际上正在尝试使用临时表来绕过 CTE 的波动性。感谢您的帮助。
    猜你喜欢
    • 2013-10-11
    • 2019-10-23
    • 1970-01-01
    • 2015-02-25
    • 2015-07-16
    • 1970-01-01
    • 1970-01-01
    • 2014-09-28
    • 1970-01-01
    相关资源
    最近更新 更多