Вы почти у цели.Просто измените порядок и используйте материал, и вы можете избавиться от необходимости использовать 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
дБ<> fiddle demo
Поскольку первая строка i % 2
равна 1
, вы знаете, что результат string_agg
всегда начинается с and
: and a or b...
Тогда все, что вы делаетеудалите первые 5 символов из этого, используя stuff
, и вы свободны дома.
Я также позволил себе заменить выражение CASE
на более короткое IIF
Обновление
Что ж, в случае, если выбранный разделитель заранее неизвестен, я не смог придумать решение для одного запроса, но все же думаю, что нашел более простое решение, чемВы опубликовали - разделяя мое первоначальное решение на cte с помощью string_agg
и выбор из него с помощью 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