使SQLite窗口聚合函数在整个表上只运行一次

bvjveswy  于 2023-10-23  发布在  SQLite
关注(0)|答案(1)|浏览(126)

什么样的SQL查询可以满足所有这些要求?我需要它来实现和测试一个窗口聚合函数。

  • agg函数必须作为窗口化聚合函数调用。
  • 结果必须是一行,其中只有一个值。
  • agg函数只能由SQLite调用一次(即一个序列)

对于本例,预期结果为:'aaa,bbb,ccc' .这些都是我的尝试,没有一个能满足上述要求。

-- preload data
CREATE TABLE tbl(a INTEGER PRIMARY KEY, b TEXT);
INSERT INTO tbl VALUES (1, 'bbb'), (2, 'ccc'), (3, 'aaa');

-- This calls window agg function multiple times
SELECT GROUP_CONCAT(b)
  OVER (ORDER BY b ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
FROM tbl;
> aaa,bbb,ccc
> aaa,bbb,ccc
> aaa,bbb,ccc

-- This is NOT a window agg func call
-- The order appears correct, but is NOT defined per SQLite docs,
--   and can change in the future
SELECT group_concat(b) FROM (SELECT b FROM tbl ORDER BY b);
> aaa,bbb,ccc

-- This is NOT a window agg func call, and the result is wrong
SELECT group_concat(b) FROM tbl ORDER BY b;
> bbb,ccc,aaa
v09wglhw

v09wglhw1#

使用明确定义的顺序进行聚合的最可靠方法是将结果限制为1:

SELECT GROUP_CONCAT(b)
  OVER (ORDER BY b ROWS
        BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
FROM tbl
LIMIT 1;

此外,上述内容可以用作子查询,例如:如果一个人想得到一个值,即使表是空的:

SELECT COALESCE(
  (
    SELECT GROUP_CONCAT(b)
    OVER (ORDER BY b ROWS
          BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
    FROM tbl
    LIMIT 1
  ),
  'the table is empty'
);

相关问题