在Select语句中使用拆分字符串表值函数

时间:2018-07-24 08:34:57

标签: sql tsql

我有一个来自第三方的表格,我无法控制。每个地址字段都包含完整地址,包括邮政编码。每个地址都有动态数量的独立地址字段。我有一个Split()TVF,它可以将地址字段拆分为单独的行。但是,当我将TVF表交叉应用回SELECT查询时,它将为TVF表中的每个ro返回一行。如何获得返回主表的一行并将TVLUM表中的行与COLUMNS分开的信息?

提供的地址示例:

a。 1街道,位置,城镇,县,邮政编码

b。 2建筑物,街道,城镇,邮政编码

c。街道,地区,乡镇,县,邮政编码3层3层

TVF使用“,”作为分隔符,将其作为每行一个值返回。然后,我需要将该数据作为每个地址字段的一列连接回原始数据。

这是我的选择查询:

select DISTINCT TOP 5 ttp.ProjectID
  ,cac.ID
  ,cac1.Proprietor1Address1
  --,CASE WHEN addr.ID = 1 THEN addr.Data END AS Address1
FROM ArdentTest.ardent.LRTitlesToProcess ttp

JOIN LandRegistryData.landreg.CommercialandCorporateOwnershipData cac
    ON ttp.TitleNo = cac.TitleNumber

JOIN (SELECT TitleNumber
            ,Proprietor1Address1
       FROM LandRegistryData.landreg.CommercialandCorporateOwnershipData
       WHERE 1 = 1
            AND ISNULL(Proprietor1Address1, '') <> '') cac1
    ON ttp.TitleNo = cac1.TitleNumber

CROSS APPLY DBAdmin.resource.Split(cac1.Proprietor1Address1, ', ') addr

WHERE 1 = 1
AND ttp.DateLRRequestSent IS NULL
AND cac.ID IN (50764, 78800, 157089, 206049, 449112)
ORDER BY 1

会产生以下结果:

ProjectID   ID      Proprietor1Address1
1010        50764   Bridge House, 1 Walnut Tree Close, Guildford, Surrey GU1 4LZ
1010        78800   Bridge House, 1 Walnut Tree Close, Guildford, Surrey GU1 4LZ
1010        157089  Bridge House, 1 Walnut Tree Close, Guildford, Surrey GU1 4LZ
1010        206049  Bridge House, 1 Walnut Tree Close, Guildford, Surrey GU1 4LZ
1010        449112  Church House, Great Smith Street, London SW1P 3AZ

我需要使用函数中的行将单独的地址列添加到结果集中,但我不知道该怎么做。

2 个答案:

答案 0 :(得分:0)

如果您可以做一些假设,例如一个地址最多可以包含10个部分。您可以使用此脚本。我使用了STRING_SPLIT而不是您的拆分功能。

DECLARE @Table TABLE (Id INT, Address VARCHAR(500))
INSERT INTO @Table VALUES
(1, '1 The Street, The Locality, The Town, The County, The Postcode'),
(2, '2 The Building, The Street, The Town, The Postcode'),
(3, 'Floor 3, 3 The Street, The Locality, The Town, The County, The Postcode')

SELECT * FROM @Table T
CROSS APPLY(
    SELECT * FROM (SELECT ROW_NUMBER()OVER(ORDER BY (SELECT NULL)) RN, * FROM STRING_SPLIT(T.Address, ','))  SRC
    PIVOT (MAX(value) FOR RN IN ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10])) PVT
) X

结果:

Id          Address                                                                          1                     2                     3                     4                     5                     6                     7                     8                     9                     10
----------- -------------------------------------------------------------------------------- --------------------- --------------------- --------------------- --------------------- --------------------- --------------------- --------------------- --------------------- --------------------- ---------------------
1           1 The Street, The Locality, The Town, The County, The Postcode                   1 The Street           The Locality          The Town              The County            The Postcode         NULL                  NULL                  NULL                  NULL                  NULL
2           2 The Building, The Street, The Town, The Postcode                               2 The Building         The Street            The Town              The Postcode         NULL                  NULL                  NULL                  NULL                  NULL                  NULL
3           Floor 3, 3 The Street, The Locality, The Town, The County, The Postcode          Floor 3                3 The Street          The Locality          The Town              The County            The Postcode         NULL                  NULL                  NULL                  NULL

答案 1 :(得分:0)

您可以从串联字符串中创建XML,并通过索引寻址每个部分

-表格(谢谢Serkan,我复制了您的DDL)

DECLARE @Table TABLE (Id INT, Address VARCHAR(500))
INSERT INTO @Table VALUES
(1, '1 The Street, The Locality, The Town, The County, The Postcode'),
(2, '2 The Building, The Street, The Town, The Postcode'),
(3, 'Floor 3, 3 The Street, The Locality, The Town, The County, The Postcode');

-此查询将逐个返回部分

WITH Splitted AS
(
    SELECT *
          ,CAST('<x>' + REPLACE((SELECT [Address] AS [*] FOR XML PATH('')),',','</x><x>') + '</x>' AS XML) AsXml
    FROM @Table
)
SELECT *
      ,AsXml.value('/x[1]','nvarchar(max)') AS Col1 
      ,AsXml.value('/x[2]','nvarchar(max)') AS Col2 
      ,AsXml.value('/x[3]','nvarchar(max)') AS Col3 
      ,AsXml.value('/x[4]','nvarchar(max)') AS Col4 
      ,AsXml.value('/x[5]','nvarchar(max)') AS Col5 
      ,AsXml.value('/x[6]','nvarchar(max)') AS Col6 
FROM Splitted

-结果

/*+----+----------------+--------------+--------------+--------------+--------------+--------------+
| ID | Col1           | Col2         | Col3         | Col4         | Col5         | Col6         |
+----+----------------+--------------+--------------+--------------+--------------+--------------+
| 1  | 1 The Street   | The Locality | The Town     | The County   | The Postcode | NULL         |
+----+----------------+--------------+--------------+--------------+--------------+--------------+
| 2  | 2 The Building | The Street   | The Town     | The Postcode | NULL         | NULL         |
+----+----------------+--------------+--------------+--------------+--------------+--------------+
| 3  | Floor 3        | 3 The Street | The Locality | The Town     | The County   | The Postcode |
+----+----------------+--------------+--------------+--------------+--------------+--------------+*/

-您可以在所有步骤上使用REVERSE。在所有情况下,这都将邮政编码放在首位(只要邮政编码是那里的最后一个元素)

WITH Splitted AS
(
    SELECT *
          ,CAST('<x>' + REPLACE((SELECT REVERSE([Address]) AS [*] FOR XML PATH('')),',','</x><x>') + '</x>' AS XML) AsXml
    FROM @Table
)
SELECT *
      ,REVERSE(AsXml.value('/x[1]','nvarchar(max)')) AS Col1 
      ,REVERSE(AsXml.value('/x[2]','nvarchar(max)')) AS Col2 
      ,REVERSE(AsXml.value('/x[3]','nvarchar(max)')) AS Col3 
      ,REVERSE(AsXml.value('/x[4]','nvarchar(max)')) AS Col4 
      ,REVERSE(AsXml.value('/x[5]','nvarchar(max)')) AS Col5 
      ,REVERSE(AsXml.value('/x[6]','nvarchar(max)')) AS Col6 
FROM Splitted;

-结果

/*+----+--------------+------------+------------+----------------+--------------+---------+
| ID | Col1         | Col2       | Col3       | Col4           | Col5         | Col6    |
+----+--------------+------------+------------+----------------+--------------+---------+
| 1  | The Postcode | The County | The Town   | The Locality   | 1 The Street | NULL    |
+----+--------------+------------+------------+----------------+--------------+---------+
| 2  | The Postcode | The Town   | The Street | 2 The Building | NULL         | NULL    |
+----+--------------+------------+------------+----------------+--------------+---------+
| 3  | The Postcode | The County | The Town   | The Locality   | 3 The Street | Floor 3 |
+----+--------------+------------+------------+----------------+--------------+---------+*/