简体   繁体   中英

SQL DB2 Select multiple columns values for multiple instances of IDs

Here is my data:

| ID | FIELD1 | FIELD2 | FIELD3 |
|-------------------------------|
| 1  |  NULL  | value1 | value2 |
|-------------------------------|
| 2  |  NULL  | value3 |  NULL  |
|-------------------------------|
| 3  | value4 |  NULL  |  NULL  |
|-------------------------------|
| 4  | value5 | value6 | value7 |
|-------------------------------|
| .. |  ...   |  ....  |  ....  |

Here is what I need to select:

| ID | ID2 | FIELDX |
|-------------------|
| 1  | 10  | value1 |
| 1  | 10  | value2 |
| 2  | 20  | value3 |
| 3  | 30  | value4 |
| 4  | 40  | value5 |
| 4  | 40  | value6 |
| 4  | 40  | value7 |
| .. | ..  |  ....  |

The order of the data doesn't really matter. What matters is that each ID appears once for every associated FIELD1,2,3... value. Please note that there are many fields. I just chose to use these three as an example.

My attempt at the solution was this query:

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;

While this does do the job, I would rather not have to add a new inner select statement for each additional field. Moreover, I feel as though there is a more efficient way to do it.

Please advise.

DB2 doesn't have an explicit unpivot and your method is fine. A more efficient method is probably to do:

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;

This doesn't necessarily simplify the code. It does make it easier for DB2 to optimize the joins. And it only requires reading table1 once instead of one time for each column.

As a note: you should use fieldx is not null rather than fieldx != null .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM