关于oracle:将多行转换为列(SQL)

Multiple rows to Columns (SQL)

我当前正在一个数据库中工作,该数据库的表如下所示:

1
2
3
4
5
6
7
8
9
ID    | TYPE   | VALUE
11111 | Type1 | 45
11111 | Type2 | 85
11111 | Type3 | 26
11111 | Type4 | 69
11112 | Type1 | 14
11112 | Type2 | 36
11113 | Type1 | 69
11113 | Type3 | 25

此表的工作方式如下:

每个ID在表中多次出现。
每个ID具有一种或多种类型。
每种类型都有一个值

在上面的示例中,您可以看到ID 11112没有Type3或Type4,而ID 11113没有Type2或Type4。

问题是,对于每个ID,这些类型中的某些(具有相应的值)应该存在,为做到这一点,应该创建一个列表,其中包含所有缺少这些类型中的一种或多种的ID。这样一来,很容易看到需要什么id并为其添加类型和值。

是否存在可以列出此类列表的查询?给出缺少一个或多个类型的每个实例的唯一ID的代码吗?我只能获取缺少特定类型的ID,但是我无法做到这一点,因此缺少任何类型的ID都会被列出。


您可以生成所有必需的类型和ID组合,然后过滤掉现有的类型和ID:

1
2
3
4
5
6
7
8
9
10
WITH required_types AS (
      SELECT 'type3' AS TYPE FROM dual UNION ALL
      SELECT 'type4' AS TYPE FROM dual
     )
SELECT i.id, rt.type
FROM (SELECT DISTINCT id FROM t) i CROSS JOIN
     required_types rt LEFT JOIN
     t
     ON t.id = i.id AND t.type = rt.type
WHERE t.id IS NULL;

如果需要数据中存在的所有类型,则可以使用(select distinct type from t)


不是很优雅,但是会返回缺少的ID和类型。我从ID中删除了多余的" 1111",从类型中删除了" ype"(太懒了,无法全部输入)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
SQL> WITH test (id, TYPE) AS
  2    (SELECT 1, 't1' FROM dual UNION ALL
  3     SELECT 1, 't2' FROM dual UNION ALL
  4     SELECT 1, 't3' FROM dual UNION ALL
  5     SELECT 1, 't4' FROM dual UNION ALL
  6     --
  7     SELECT 2, 't1' FROM dual UNION ALL
  8     SELECT 2, 't2' FROM dual UNION ALL
  9     --
 10     SELECT 3, 't1' FROM dual UNION ALL
 11     SELECT 3, 't3' FROM dual
 12    ),
 13  all_types AS
 14    (SELECT DISTINCT TYPE FROM test)
 15  --
 16  SELECT t.id, a.type
 17  FROM test t JOIN all_types a ON 1 = 1
 18  minus
 19  SELECT t.id, t.type
 20  FROM test t;

        ID TY
---------- --
         2 t3
         2 t4
         3 t2
         3 t4

SQL>


此查询显示至少缺少一种类型的所有ID:

1
2
3
4
SELECT ID
FROM T
GROUP BY ID
HAVING COUNT(DISTINCT TYPE)<(SELECT COUNT(DISTINCT TYPE) FROM T)