作为聚合或窗口函数的一部分,从多行评估值

时间:2016-02-04 00:22:25

标签: postgresql aggregate-functions

我需要找到一种方法来判断列是否在分组/分区部分中有两个特定值。最容易通过示例来描述。我有“foo”表,其中包含以下数据:

ID | Indicator
1  | A
1  | B
1  | B
2  | C
2  | B
3  | A
3  | B
3  | B
3  | C
4  | A
4  | C

对于我的输出,如果组中的一行具有指示符“A”,则我想要“A”的结果。如果不是,那么如果其中一行指标是“C”则为“C”。但是如果该组的指标为“A”且指标为“C”,则我希望该组的结果为“X”。根据数据,我想得到以下结果:

ID | Result
1  | A
2  | C
3  | X
4  | X

A或C的结果(示例中的ID 1和2)可以使用分区和窗口函数以这种方式完成:

SELECT DISTINCT ID,
                priority_indicator
  FROM (SELECT ID,
               first_value(Indicator) OVER
               (PARTITION BY ID
                    ORDER BY
                      CASE
                        WHEN Indicator = 'A' THEN
                          1
                        WHEN Indicator = 'C' THEN
                          2
                        ELSE
                          3
                      END
               ) priority_indicator
          FROM foo) a

当指标中同时出现“A”和“C”时,您如何一次查看多行中的值以返回“X”?

1 个答案:

答案 0 :(得分:2)

--test data
WITH foo(id,indicator) AS ( VALUES
  (1,'A'),
  (1,'B'),
  (1,'B'),
  (2,'C'),
  (2,'B'),
  (3,'A'),
  (3,'B'),
  (3,'B'),
  (3,'C'),
  (4,'A'),
  (4,'C')
), 
-- get all entries for each Id in indicator_set
agg AS (
  SELECT id,array_agg(DISTINCT(indicator)) AS indicator_set FROM foo
  GROUP BY id
)
-- actual query
SELECT id,
  CASE
    WHEN indicator_set @> '{A,C}' THEN 'X'
    WHEN indicator_set @> '{A}' THEN 'A'
    WHEN indicator_set @> '{C}' THEN 'C'
  END result
FROM agg;

输出:

 id | result 
----+--------
  1 | A
  2 | C
  3 | X
  4 | X
(4 rows)