在列分配中跳过NULL值

时间:2019-05-31 12:28:47

标签: sql sql-server sql-server-2016

有一个数据库表,其中包含地址信息,例如

+--------------------------------------------------------------+
| name1       | name2 | name3 | street        | zip     | city |
+--------------------------------------------------------------+
| 'Some name' | NULL  | ''    | 'Some street' | '12345' | NULL |
+--------------------------------------------------------------+

因此某些字段可能为NULL或为空。

现在我要选择

SELECT
  name1,  /* 'Some name' */
  name2,  /* NULL */
  name3,  /* '' */
  street, /* 'Some street' */
  zip,    /* '12345' */
  city,   /* NULL */

  adr1,   /* Should contain 'Some name' */
  adr2,   /* Should contain 'Some street' */
  adr3,   /* Should contain '12345' */
  adr4,   /* NULL */
  adr5,   /* NULL */
  adr6    /* NULL */
FROM
 adr

其中adr16代表信头行,应按name1name2name3streetzipcity,但在赋值时应跳过NULL或空值。

有人知道如何实现吗?

1 个答案:

答案 0 :(得分:1)

这有点混乱,并且依赖于您有一个ID列,但是,我认为这是您想要的:

WITH CTE AS(
    SELECT S.YourID,
           S.name1,
           S.name2,
           S.name3,
           S.street,
           S.zip,
           S.city,
           NULLIF(V.Adr,'') AS Adr,
           Line,
           ROW_NUMBER() OVER (PARTITION BY YourID, CASE WHEN NULLIF(V.Adr,'') IS NULL THEN 1 ELSE 0 END ORDER BY Line) AS RN
    FROM (VALUES(1, 'Some name',CONVERT(varchar(10),NULL),'','Some street','12345',CONVERT(varchar(10),NULL))) S(YourID,name1,name2,name3,street,zip,city)
         CROSS APPLY(VALUES(name1,1),(name2,2),(name3,3),(street,3),(zip,4),(city,5)) V(Adr,Line))
SELECT C.YourID,
       MAX(C.name1) AS name1,
       MAX(C.name2) AS name2,
       MAX(C.name3) AS name3,
       MAX(C.street) AS street,
       MAX(C.zip) AS zip,
       MAX(C.city) AS city,
       MAX(CASE WHEN C.RN = 1 THEN C.Adr END) AS Adr1,
       MAX(CASE WHEN C.RN = 2 THEN C.Adr END) AS Adr2,
       MAX(CASE WHEN C.RN = 3 THEN C.Adr END) AS Adr3,
       MAX(CASE WHEN C.RN = 4 THEN C.Adr END) AS Adr4,
       MAX(CASE WHEN C.RN = 5 THEN C.Adr END) AS Adr5,
       MAX(CASE WHEN C.RN = 6 THEN C.Adr END) AS Adr6
FROM CTE C
WHERE C.Adr IS NOT NULL
GROUP BY C.YourID;