使用多个ISNULL的SQL IF语句

时间:2019-01-11 20:27:30

标签: sql sql-server tsql sql-server-2012 concat

我有以下代码返回了邮政编码的访问顺序。我能够正确返回邮政编码,但是为了使数据更加用户友好,我在邮政编码之间添加了破折号(-)。

问题来自以下事实:我无法弄清楚如何消除仅包含2或3个邮政编码的行的破折号。

enter image description here

SELECT 
    [Qry_Zip Stop Sequence].[Load ID], 
    [1] AS [Stop 1], [2] AS [Stop 2], [3] AS [Stop 3], 
    [4] AS [Stop 4], 
    TMS_Load.[Shipped Date/Time], 
    CONCAT(ISNULL([1], ''), '-', ISNULL([2], ''), '-', ISNULL([3], ''), '-', ISNULL([4], '')) AS [Zip to Zip w Stops]
FROM 
    (SELECT 
         [Load ID], [Sequence], [Stop Zip]
     FROM 
         TMS_Load_Stops) ls
PIVOT 
    (MIN([Stop Zip])
        FOR [Sequence] IN ([1], [2], [3], [4])) AS [Qry_Zip Stop Sequence]
INNER JOIN 
    [TMS_Load] ON [TMS_Load].[Load ID] = [Qry_Zip Stop Sequence].[Load ID]; 

我希望结果只显示有效邮政编码之间的破折号。

78052-45050-45201 or
73350-45220 or
84009-48009-14452 or
36521-38222-87745-95123 or
73368 or
12789-35789

3 个答案:

答案 0 :(得分:2)

SQL Server 2017支持CONCAT_WS,它是为这种情况而设计的:

  

CONCAT_WS在连接期间会忽略空值,并且不会在空值之间添加分隔符。因此,CONCAT_WS可以干净地处理可能具有“空白”值的字符串的连接-例如,第二个地址字段

SELECT *, CONCAT_WS('-', Stop1, Stop2, Stop3, Stop4) AS r
FROM tab

db<>fiddle demo

答案 1 :(得分:2)

使用一个破折号为每个值添加前缀,并使用stuff()删除结果字符串中的第一个破折号-不一定是第一个值中的第一个破折号。

stuff(concat('-' + [1],
             '-' + [2],
             '-' + [3],
             '-' + [4]),
      1,
      1,
      '')

注意:我在这里故意将+concat()混合在一起进行字符串连接。当值为+NULL会产生NULL,但是concat()会将NULL视为空字符串。这样,我们就不需要使用大量的coalesce()isnull()等。

答案 2 :(得分:1)

以下代码将仅对非NULL值插入分隔符。假定列是从左到右填充的。

declare @Stops as Table ( Stop1 Char(5), Stop2 Char(5), Stop3 Char(5), Stop4 Char(5) );
insert into @Stops ( Stop1, Stop2, Stop3, Stop4 ) values
  ( '00001', null, null, null ),
  ( '00001', '00002', null, null ),
  ( '00001', '00002', '00003', null ),
  ( '00001', '00002', '00003', '00004' );


select Coalesce( Stop1, '' ) + Coalesce( '>' + Stop2, '' ) + Coalesce( '>' + Stop3, '' ) +
  Coalesce( '>' + Stop4, '' )
  from @Stops;

此外:在使用ZIP + 4代码的区域中,破折号以外的分隔符可能不太容易混淆。