仅在存在字符时优化拆分列

时间:2013-09-15 09:32:48

标签: sql sql-server sql-server-2008

我有一张表UtilityPin,如下所示:

UtilityID   PinType    PinValue     PinLatitude  PinLongitude
---------------------------------------------------------------
ABC         Zip        90222-3804   33.903808   -118.240723
ABC         Zip        90230-4313   34.008245   -118.388507
ABC         Zip        90230-4941   34.003206   -118.396149
ABC         Zip        90230        34.001654   -118.395662

现在,PinValue列包含区域的Zip-Zip4值,我想从中提取Zip Zip4,并且当行中没有Zip4时格式为Zip没有连字符,可以在最后一行看到,这意味着Zip4必须为空。

所以在研究和查看像this这样的Stack问题后,我最终得到了以下查询:

Select
    Zip = CASE WHEN CHARINDEX('-', h.PinValue) >0 THEN  SUBSTRING(h.PinValue, 0, CHARINDEX('-', h.PinValue)) ELSE h.PinValue END,
    Zip4 = CASE WHEN CHARINDEX('-', h.PinValue) >0 THEN SUBSTRING(h.PinValue, CHARINDEX('-', h.PinValue) + 1, LEN(h.PinValue) - CHARINDEX('-', h.PinValue)) 
    ELSE '' END
FROM 
    UtilityPin h
WHERE 
h.UtilityID ='ABC'  

哪个正常工作并给出了我想要的结果但是正如您在上面的查询中所看到的那样,我必须在-中检查PinValue两次的存在,这正在进行冗余操作,因为我有将其拆分为两列ZipZip4。基本上我想要这样的东西:

--this query gives an error
Select 
    CASE WHEN CHARINDEX('-', h.PinValue) >0
    THEN
        SUBSTRING(h.PinValue, 0, CHARINDEX('-', h.PinValue)) AS Zip, 
        SUBSTRING(h.PinValue, CHARINDEX('-', h.PinValue) + 1, LEN(h.PinValue) - CHARINDEX('-', h.PinValue)) AS Zip4 
    ELSE
        h.PinValue AS Zip, 
        '' AS Zip4 
from 
    UtilityPin h
WHERE 
    h.PinType ='ABC'

所以我只会在-中查看PinValue一次,但上面的查询是错误的,我也使用了IF..ElSE,但是它给出了错误。

非常感谢任何建议。

1 个答案:

答案 0 :(得分:1)

如果我没有弄错,zip格式是固定的,因此你可以这样做

SELECT LEFT(PinValue, 5) Zip,
       CASE WHEN LEN(PinValue) = 10 THEN RIGHT(PinValue, 4) END Zip4
  FROM UtilityPin
 WHERE UtilityID ='ABC'

甚至

SELECT LEFT(PinValue, 5) Zip,
       SUBSTRING(PinValue, 7, 4) Zip4
  FROM UtilityPin
 WHERE UtilityID ='ABC'

注意:在第二个查询中,如果某个值不包含最后四位,您将在NULL中获得一个空字符串而不是zip4。您可以使用NULLIF()COALESCE()

的任一方式解决此问题

示例输出:

|   ZIP |   ZIP4 |
|-------|--------|
| 90222 |   3804 |
| 90230 |   4313 |
| 90230 |   4941 |
| 90230 | (null) |

以下是两个查询的 SQLFiddle 演示