在 Postgres 中对条件数据进行排序 STRING_AGG

Sort conditional data in Postgres STRING_AGG

我提出了一个查询,以在 Postgress 中使用 STRING_AGG 基于条件语句创建串联字符串。这很好用,但我也想在不复制 CASE.

的情况下对结果进行排序

这是我现在拥有的:

SELECT
STRING_AGG(distinct name, ', ' ORDER BY name),
STRING_AGG(
  DISTINCT
  CASE WHEN something = true THEN 'type1'
       WHEN something_else = true THEN 'type2'
       ELSE 'type3'
  END, ', '
ORDER BY
  CASE WHEN something = true THEN 'type1'
       WHEN something_else = true THEN 'type2'
       ELSE 'type3'
  END

)
from organisations

..但我想做这样的事情来避免重复的代码并从我的查询中删除行和复杂性但我不知道如何让它工作,这是假代码显然有效,但你明白了:

SELECT
STRING_AGG(distinct name, ', ' ORDER BY name) names,
STRING_AGG(
  DISTINCT (
    CASE WHEN something = true THEN 'type1'
         WHEN something_else = true THEN 'type2'
         ELSE 'type3'
    END
  ) as types, ', ' ORDER BY types) types
from organisations

一个选项可能是先在单独的 CTE 中计算 CASE 表达式,然后查询该 CTE 以应用 STRING_AGG:

WITH cte AS (
    SELECT
        name,
        CASE WHEN something = true THEN 'type1'
             WHEN something_else = true THEN 'type2'
             ELSE 'type2'
        END AS expr
    FROM organisations
)

SELECT
    STRING_AGG(distinct name, ', ' ORDER BY name),
    STRING_AGG(DISTINCT expr, ', ' ORDER BY expr)
FROM cte;

作为一个小的旁注,因为你有 type2 作为 CASE 表达式中的第二个和 ELSE 条件,你最好使用这个:

CASE WHEN something = true THEN 'type1'
     ELSE 'type2'
END

您不需要 string_agg()。你可以改为:

SELECT STRING_AGG(distinct name, ', ' ORDER BY name) names,
       CONCAT_WS(',',
                 (CASE WHEN SUM( (something = true)::int ) > 0 THEN 'type1'),
                 (CASE WHEN SUM( (not (something = true) )::int ) > 0 THEN 'type2')
                ) as types
FROM organisations o;

您可能过于简化了查询,但对于您提供的内容,第二部分不需要 string_agg(distinct)