分组到列并用唯一的排名行填充列

时间:2018-09-28 20:22:52

标签: sql oracle

我正在基于具有事件结果的表进行查询。每行都有一个团队参加,并且他们在该事件中的位置(最多4个团队)。我想以此为基础运行查询,以对该事件进行分组,并为每个展示位置创建一列,并用该事件期间获得该排名的团队填充该列。

为此,我创建了一些字段(first_place,second_place等),用于根据rank列检查条件案例语句,如果团队获得了与该列相对应的结果,它将使用该团队的名称填充该列。

我遇到的问题是,如果我不将案例添加到组中,则会出错(至少在Oracle中,SQL Fiddle会处理它,但结果仍然是错误的)。如果我将它们添加到group子句中,则它将为每个团队输出1行,并将其余列排为NULL。

这对于像这样进行分组是有意义的,但似乎找不到解决方法。我试图使用像COALESCE之类的东西,但是找不到像这样的函数作为聚合函数。

下面的

SQL Fiddle和DDL供您参考。非常感谢您的协助。

http://sqlfiddle.com/#!9/8ae4c9/1

表定义

CREATE TABLE Table1
    (`pk_id` int, `evt_id` int, `team` varchar(5), `rank` int)
;

INSERT INTO Table1
    (`pk_id`, `evt_id`, `team`, `rank`)
VALUES
    (1, 1, 'TeamA', 1),
    (2, 1, 'TeamB', 2),
    (3, 1, 'TeamC', 3),
    (4, 1, 'TeamD', 4),
    (5, 2, 'TeamD', 1),
    (6, 2, 'TeamB', 2),
    (7, 2, 'TeamC', 3),
    (8, 2, 'TeamA', 4),
    (9, 3, 'TeamB', 1),
    (10, 3, 'TeamD', 2),
    (11, 3, 'TeamC', 3),
    (12, 3, 'TeamA', 4),
    (13, 4, 'TeamD', 1),
    (14, 4, 'TeamC', 2),
    (15, 4, 'TeamA', 3),
    (16, 4, 'TeamB', 4)
;

查询

SELECT
  evt_id,
  CASE rank WHEN 1 THEN team END as first_place,
  CASE rank WHEN 2 THEN team END as second_place,
  CASE rank WHEN 3 THEN team END as third_place,
  CASE rank WHEN 4 THEN team END as fourth_place
FROM
  Table1
GROUP BY
  evt_id
;

当前结果

+--------+-------------+--------------+-------------+--------------+
| evt_id | first_place | second_place | third_place | fourth_place |
+--------+-------------+--------------+-------------+--------------+
|      1 | TeamA       | (null)       | (null)      | (null)       |
|      1 | (null)      | TeamB        | (null)      | (null)       |
|      1 | (null)      | (null)       | TeamC       | (null)       |
|      1 | (null)      | (null)       | (null)      | TeamD        |
|      2 | TeamD       | (null)       | (null)      | (null)       |
|      2 | (null)      | TeamB        | (null)      | (null)       |
|      2 | (null)      | (null)       | TeamC       | (null)       |
|      2 | (null)      | (null)       | (null)      | TeamA        |
|      3 | TeamB       | (null)       | (null)      | (null)       |
|      3 | (null)      | TeamD        | (null)      | (null)       |
|      3 | (null)      | (null)       | TeamC       | (null)       |
|      3 | (null)      | (null)       | (null)      | TeamA        |
|      4 | TeamD       | (null)       | (null)      | (null)       |
|      4 | (null)      | TeamC        | (null)      | (null)       |
|      4 | (null)      | (null)       | TeamA       | (null)       |
|      4 | (null)      | (null)       | (null)      | TeamB        |
+--------+-------------+--------------+-------------+--------------+

预期产量

+--------+-------------+--------------+-------------+--------------+
| evt_id | first_place | second_place | third_place | fourth_place |
+--------+-------------+--------------+-------------+--------------+
|      1 | TeamA       | TeamB        | TeamC       | TeamD        |
|      2 | TeamD       | TeamB        | TeamC       | TeamA        |
|      3 | TeamB       | TeamD        | TeamC       | TeamA        |
|      4 | TeamD       | TeamC        | TeamA       | TeamB        |
+--------+-------------+--------------+-------------+--------------+

1 个答案:

答案 0 :(得分:2)

我认为您只需要一些聚合功能:

SELECT evt_id,
       MAX(CASE rank WHEN 1 THEN team END) as first_place,
       MAX(CASE rank WHEN 2 THEN team END) as second_place,
       MAX(CASE rank WHEN 3 THEN team END) as third_place,
       MAX(CASE rank WHEN 4 THEN team END) as fourth_place
FROM Table1
GROUP BY evt_id;