选择查询以将空值推送到地址行中的最后一列

时间:2017-02-24 02:34:35

标签: sql sql-server

我需要编写一个查询来选择地址行,以便将空值推送到最后一列。例如,如果表格具有以下数据

ID, line1, line2, line3, line4, line5, line6
1   null   test2  test3  test4  test5  test6
2   test1  test2  test3  test4  test5  test6
3   null   null   null   null   test5  test6
4   test1  test2  test3  null   test5  test6

查询的输出应如下

ID, line1, line2, line3, line4, line5, line6
1   test2  test3  test4  test5  test6  null
2   test1  test2  test3  test4  test5  test6
3   test5  test6  null   null   null   null
4   test1  test2  test3  test5  test6  null

我尝试通过消除空值来将值与分隔符连接,然后再次拆分值,但由于实际数据包含不支持xml的字符,因此我很难将值拆分回来。有没有一种简单的方法来完成创建要拆分的功能?如果值中没有导致转换为xml失败的字符

,则下面有效
SELECT
  ISNULL(Line1 + '|', '')
+ ISNULL(Line2 + '|', '')
+ ISNULL(Line3 + '|', '')
 + ISNULL(Line4 + '|', '')
  + ISNULL(Line5 + '|', '')
   + ISNULL(Line6 , '')  as tmpaddr 
FROM #addr1

SELECT DISTINCT id,
S.a.value('(/H/r)[1]', 'VARCHAR(100)') AS line1,
S.a.value('(/H/r)[2]', 'VARCHAR(100)') AS line2,
S.a.value('(/H/r)[3]', 'VARCHAR(100)') AS line3,
S.a.value('(/H/r)[4]', 'VARCHAR(100)') AS line4,
S.a.value('(/H/r)[5]', 'VARCHAR(100)') AS line5,
S.a.value('(/H/r)[6]', 'VARCHAR(100)') AS line6
FROM
(
SELECT *,CAST (N'<H><r>' + REPLACE(tmpaddr , '|', '</r><r>')  + '</r></H>'      AS XML) AS [vals]
FROM #addr ) d 
CROSS APPLY d.[vals].nodes('/H/r') S(a)

1 个答案:

答案 0 :(得分:0)

我假设您正在使用SQL Server,基于语法约定。

您可以使用cross apply和聚合:

执行您想要的操作
SELECT a.id, t.*
FROM #addr1 a CROSS APPLY
     (SELECT MAX(CASE WHEN seqnum = 1 THEN line END) as line1,
             MAX(CASE WHEN seqnum = 2 THEN line END) as line2,
             MAX(CASE WHEN seqnum = 3 THEN line END) as line3,
             MAX(CASE WHEN seqnum = 4 THEN line END) as line4,
             MAX(CASE WHEN seqnum = 5 THEN line END) as line5,
             MAX(CASE WHEN seqnum = 6 THEN line END) as line6
      FROM (SELECT num, line, ROW_NUMBER() OVER (ORDER BY num) as seqnum
            FROM (VALUES (1, a.line1),
                         (2, a.line2),
                         (3, a.line3),
                         (4, a.line4),
                         (5, a.line5),
                         (6, a.line6)
                 ) v(num, line)
            WHERE line IS NOT NULL
           ) t
     ) t;