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

问题描述 投票:0回答:1

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

  • agg 函数必须作为 windowing 聚合函数调用。
  • 结果必须是单行,其中包含单个值。
  • 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
sqlite
1个回答
0
投票

使用明确定义的顺序进行聚合的最可靠方法是将结果简单地限制为 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'
);
© www.soinside.com 2019 - 2024. All rights reserved.