SQL Server-STRING_AGG分隔符作为条件表达式

时间:2019-02-10 12:39:02

标签: sql sql-server tsql sql-server-2017 string-aggregation

我需要基于任意逻辑使用不同的分隔符来连接行。例如:

CREATE TABLE t(i INT, c VARCHAR(10));
INSERT INTO t(i,c) VALUES(1, 'a'),(2, 'b'),(3, 'c'),(4, 'd'),(5, 'e');

SELECT STRING_AGG(c,(CASE WHEN i%2=0 THEN ' OR ' ELSE ' AND ' END)) 
       WITHIN GROUP (ORDER BY i) AS r
FROM t;

db<>fiddle demo

它以错误结尾:

  STRING_AGG的

分隔符参数必须为字符串文字变量

我的最终目标是获得:a OR b AND c OR d AND e,例如: db<>fiddle demo


注意:我知道XML + STUFF@var = @var + ...

我正在搜索特定于STRING_AGG的“解决方法”。


编辑:我已将其添加为Azure Feedback

上的提示

2 个答案:

答案 0 :(得分:1)

您快到了。只需颠倒顺序并使用东西,就可以消除对cte和大多数字符串函数的需要:

SELECT STUFF(
           STRING_AGG(
               (IIF(i % 2 = 0, ' OR ', ' AND '))+c
           , '') WITHIN GROUP (ORDER BY i)
           , 1, 5, '') AS r
FROM t;

结果:a OR b AND c OR d AND e

db<>fiddle demo

由于第一行i % 2等于1,所以您知道string_agg的结果将始终以and开头:and a or b... 然后,您要做的就是使用stuff从其中删除前5个字符,这样您就可以自由回家了。

我也自由地将CASE表达式替换为较短的IIF

更新

好吧,在事先不知道所选分隔符的情况下,我无法提出一个查询解决方案,但我仍然认为我找到了比您发布的更为简单的解决方案-将我的初始解决方案分隔为一个使用string_agg进行cte,并使用stuff从中进行选择,同时通过重复条件来确定定界符的长度:

WITH CTE AS
(
SELECT MIN(i) As firstI,
       STRING_AGG(
               (IIF(i % 2 = 0, ' OR ', ' AND '))+c
           , '') WITHIN GROUP (ORDER BY i)
       AS r
FROM t
)

SELECT STUFF(r, 1, IIF(firstI % 2 = 0, 4, 5), '') AS r
FROM CTE;

db<>fiddle demo #2

答案 1 :(得分:0)

一种可能的解决方案(不理想)是将分隔符移至主表达式并将分隔符设置为空白:

std::shared_ptr<std::vector<uint8_t>> sPtr (&mVector,[](std::vector<uint8_t>*){});

db<>fiddle demo