这是我的数据:
| ID | FIELD1 | FIELD2 | FIELD3 |
|-------------------------------|
| 1 | NULL | value1 | value2 |
|-------------------------------|
| 2 | NULL | value3 | NULL |
|-------------------------------|
| 3 | value4 | NULL | NULL |
|-------------------------------|
| 4 | value5 | value6 | value7 |
|-------------------------------|
| .. | ... | .... | .... |
以下是我需要选择的内容:
| ID | ID2 | FIELDX |
|-------------------|
| 1 | 10 | value1 |
| 1 | 10 | value2 |
| 2 | 20 | value3 |
| 3 | 30 | value4 |
| 4 | 40 | value5 |
| 4 | 40 | value6 |
| 4 | 40 | value7 |
| .. | .. | .... |
数据的顺序并不重要。重要的是每个ID对于每个相关的FIELD1,2,3 ...值都会出现一次。请注意,有很多领域。我只是选择使用这三个作为例子。
我对解决方案的尝试是这个查询:
SELECT x.ID, a.ID2, x.FIELDX
FROM (
SELECT t.ID, t.FIELD1
FROM SCHEMA1.TABLE1 t
UNION ALL
SELECT t.ID, t.FIELD2
FROM SCHEMA1.TABLE1 t
UNION ALL
SELECT t.ID, t.FIELD3
FROM SCHEMA1.TABLE1 t
) x
JOIN SCHEMA2.TABLE2 a ON x.ID = a.ID
WHERE x.FIELDX != NULL
WITH UR;
虽然这确实有效,但我不想为每个额外的字段添加新的内部select语句。而且,我觉得有一种更有效的方法可以做到这一点。
请告知。
答案 0 :(得分:2)
DB2没有明确的unpivot
,您的方法很好。一种更有效的方法可能是:
SELECT id, id2, fieldx
FROM (SELECT x.ID, a.ID2,
(case when col = 'field1' then field1
when col = 'field2' then field2
when col = 'field3' then field3
end) as FIELDX
FROM SCHEMA1.TABLE1 x join
SCHEMA2.TABLE2 a
on x.ID = a.ID cross join
(select 'field1' as col from sysibm.sysdummy1 union all
select 'field2' from sysibm.sysdummy1 union all
select 'field3' from sysibm.sysdummy1
) c
) x
WHERE x.FIELDX is not NULL;
这不一定简化代码。它确实使DB2更容易优化连接。它只需要一次读取table1
而不是每列读取一次。
注意:您应该使用fieldx is not null
而不是fieldx != null
。