如果所有列都返回空列或仅返回非空列,如何仅返回一条记录

时间:2019-05-15 11:57:45

标签: sql oracle plsql

我需要一种方法来处理以下情况。

编写查询以转换以下结果集

ID|Location|NameA|ValueA|NameB|ValueB
__|________|_____|______|_____|______|
0 |   BL   |NULL |NULL  |NULL |NULL  |
__|________|_____|______|_____|______|
1 |   GT   |x    |y     |NULL |NULL  |
__|________|_____|______|_____|______|
2 |   SZ   |c    |d     |e    |f     |

...对此

ID|Location|Name |Value |
__|________|_____|______|
0 |   BL   |NULL |NULL  |
__|________|_____|______|
1 |   GT   |x    |y     |
__|________|_____|______|
2 |   SZ   |c    |d     |
 _|________|_____|______|
2 |   SZ   |e    |f     |

对于具有所有“名称/值”列为NULL的记录,我不希望在结果表中有两个记录,我只需要一个,而对于具有多个NON-NULL的记录我希望名称/值对显示为结果表的单独记录,而NULL则将名称/值对忽略。

4 个答案:

答案 0 :(得分:1)

在Oracle 12C中,您可以为此使用横向联接。在早期版本中,最简单的方法可能是union all

select id, location, nameA as name, valueA as value
from t
union all
select id, location, nameB as name, valueB as value
from t
where nameB is not null;

答案 1 :(得分:1)

这涵盖了nameAvalueA都为空而nameBvalueB不为空的情况:

select id, location, namea name, valuea value
from tablename
where namea is not null or valuea is not null
union all
select id, location, nameb, valueb
from tablename
where nameb is not null or valueb is not null
union all
select id, location, null, null
from tablename
where namea is null and valuea is null and nameb is null and valueb is null
order by id

请参见demo

答案 2 :(得分:0)

SELECT
    id,
    location,
    COALESCE(nameA,  nameB )   AS name,
    COALESCE(valueA, valueB)   AS value
FROM
    yourtable

UNION ALL

SELECT
    id,
    location,
    nameB,
    valueB
FROM
    yourTable
WHERE
        nameA IS NOT NULL
    AND nameB IS NOT NULL

答案 3 :(得分:0)

执行此操作的另一种方法是使用UNPIVOT

-- Sample Data:
WITH dat(ID,Location,NameA,ValueA,NameB,ValueB) AS
  (SELECT 0 ,   'BL'   ,NULL ,NULL  ,NULL ,NULL  FROM dual
    UNION
   SELECT 1 ,   'GT'   ,'x'  ,'y'   ,NULL ,NULL  FROM dual
    UNION
   SELECT 2 ,   'SZ'   ,'c'  ,'d'   ,'e'  ,'f'   FROM dual)

-- SQL-Statement:
SELECT id,location, NAME, value 
  FROM dat
  UNPIVOT INCLUDE NULLS(
    (NAME, VALUE) FOR sk IN ((NameA, ValueA) AS 1
                            ,(NameB, ValueB) AS 2)
  )
  WHERE SK = 1 OR NAME IS NOT NULL