如何在不使用子查询的情况下将Oracle中的行转换为列,并显示列的所有可能值(即使某些值不存在)?

lnlaulya  于 2023-06-05  发布在  Oracle
关注(0)|答案(1)|浏览(187)

使用Oracle 19 c。我正在尝试编写一个将值转换为列的查询。以下是示例数据:
| 测试ID|用户ID|测试类型|结果|测试日期|
| - -----|- -----|- -----|- -----|- -----|
| 0001| 0001|测试A01| ++|2017年8月3日|
| 0001| 0001|测试A01| ++|23年3月11日|
| 0002| 0001|测试A02|- 你好|23年3月11日|
| 0003| 0001|测试B 08|- 你好|23年3月11日|
| 0004| 0001|测试B17| ++|23年3月11日|
| 零零五|0002|测试A01| ++|23年3月11日|
| 0006| 0002|测试B 08| ++|23年3月11日|
| 零零七|0003|测试A02|- 你好|23年3月11日|
下面是我想要显示数据的方式:
| 动物ID| A01| A02|公司简介|B17|
| - -----|- -----|- -----|- -----|- -----|
| 0001| |- 你好|- 你好||
| 0002| ++| U| U| ++|
| 0003| U|- 你好|U| U|
我的限制-只采取最新的测试日期(完全可能有多个结果为每个用户);列出所有4种测试类型,如果没有值,则列出“U”或空白。
我知道如何在值上执行ListAgg,但我不知道如何强制显示所有4个值,即使有些值不存在。我已经使用了四个子查询(A01,A02,B 08,B17各一个),但是查询性能太慢了。我欢迎你的建议。

56lgkhnf

56lgkhnf1#

如果您知道可能出现在TEST_TYPE列中的值-您可以使用PIVOT语句:

WITH      -- Sample Data
    tbl AS 
        (   Select  '0001' "TEST_ID",   '0001' "USER_ID",   'TestA01' "TEST_TYPE",  '+' "A_RESULT", To_Date('03-AUG-17', 'dd-MON-yy') "TEST_DATE" From Dual Union All
            Select  '0001', '0001', 'TestA01',  '+', To_Date('11-MAR-23', 'dd-MON-yy') From Dual Union All
            Select  '0002', '0001', 'TestA02',  '-', To_Date('11-MAR-23', 'dd-MON-yy') From Dual Union All
            Select  '0003', '0001', 'TestB08',  '-', To_Date('11-MAR-23', 'dd-MON-yy') From Dual Union All
            Select  '0004', '0001', 'TestB17',  '+', To_Date('11-MAR-23', 'dd-MON-yy') From Dual Union All
            Select  '0005', '0002', 'TestA01',  '+', To_Date('11-MAR-23', 'dd-MON-yy') From Dual Union All
            Select  '0006', '0002', 'TestB08',  '+', To_Date('11-MAR-23', 'dd-MON-yy') From Dual Union All
            Select  '0007', '0003', 'TestA02',  '-', To_Date('11-MAR-23', 'dd-MON-yy') From Dual 
        )
--  M a i n   S Q L :
Select USER_ID "ANIMAL_ID", Nvl(Max(A01), 'U') "A01", Nvl(Max(A02), 'U') "A02", Nvl(Max(B08), 'U') "B08", Nvl(Max(B17), 'U') "B17"
From (  Select * 
        From tbl
     )  PIVOT( Max(A_RESULT) FOR TEST_TYPE IN('TestA01' as A01, 'TestA02' as A02, 'TestB08' as B08, 'TestB17' as B17)  )
Group By USER_ID
Order By USER_ID
--  
--  R e s u l t :
--  AnimalID  A01  A02  B08  B17
--  --------  ---  ---  ---  ---
--  0001      +    -    -    +
--  0002      +    U    U    +
--  0003      U    -    U    U

如果你只想要最新的测试日期,那么结果数据集会有点不同:

Select USER_ID "ANIMAL_ID", Nvl(Max(A01), 'U') "A01", Nvl(Max(A02), 'U') "A02", Nvl(Max(B08), 'U') "B08", Nvl(Max(B17), 'U') "B17"
From (  Select * 
        From tbl
        Where TEST_DATE = (Select Max(TEST_DATE) From tbl)
     )  PIVOT( Max(A_RESULT) FOR TEST_TYPE IN('TestA01' as A01, 'TestA02' as A02, 'TestB08' as B08, 'TestB17' as B17)  )
Group By USER_ID
Order By USER_ID
--  
--  R e s u l t :
--  AnimalID  A01  A02  B08  B17
--  --------  ---  ---  ---  ---
--  0001      +    -    -    +
--  0002      +    U    +    U
--  0003      U    -    U    U

相关问题