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

时间:2018-04-15 14:07:09

标签: sql postgresql string-aggregation

我想出了一个查询,根据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

2 个答案:

答案 0 :(得分:2)

您不需要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)

答案 1 :(得分:1)

一个选项可能是首先在单独的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表达式中的第二个和ELSE条件都有CASE,因此您可以使用它:

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