4

所以这是一个非常标准的要求;我有一个包含地址信息的表,我想提取一个单一的“格式化”地址,其中所有字段都用逗号分隔符连接。

问题是某些字段可以为 NULL,因此我以逗号结尾。例如,一个地址可能是“10 The Strand, London”,最后没有国家,但下一个地址可能是“5 Fleet Street, London, England”。如果我挑选出每个地址元素并假设它始终存在,那么我会将这两个地址表示为:

“伦敦舰队街 5 号”

"10 The Strand, , , 伦敦, 英国"

去掉中间多余的逗号很简单,只是对 NULL 的测试。

我知道如何使用 CTE 或子查询在两遍中解决尾随逗号问题,但是这可以在单遍数据中完成吗?

以下是使用 CTE 的示例:

DECLARE @Address TABLE (
    Name VARCHAR(255),
    Line1 VARCHAR(255),
    Line2 VARCHAR(255),
    Line3 VARCHAR(255),
    City VARCHAR(255),
    Country VARCHAR(255));
INSERT INTO @Address VALUES ('Complete', 'Test 1', 'Test 2', 'Test 3', 'Oxford', 'England');
INSERT INTO @Address VALUES ('Incomplete', '22 Accacia', NULL, NULL, 'York', 'England');
INSERT INTO @Address VALUES ('Missing End', '10 Bond Street', NULL, NULL, 'London', NULL);
WITH Addresses AS
(
SELECT
    CASE WHEN Name IS NULL THEN '' ELSE Name + ', ' END + 
    CASE WHEN Line1 IS NULL THEN '' ELSE Line1 + ', ' END + 
    CASE WHEN Line2 IS NULL THEN '' ELSE Line2 + ', ' END + 
    CASE WHEN Line3 IS NULL THEN '' ELSE Line3 + ', ' END + 
    CASE WHEN City IS NULL THEN '' ELSE City + ', ' END + 
    CASE WHEN Country IS NULL THEN '' ELSE Country + ', ' END AS [Address]
FROM
    @Address)
SELECT LEFT([Address], LEN([Address]) - 1) AS [Address Clean] FROM Addresses;

这给了我:

Complete, Test 1, Test 2, Test 3, Oxford, England
Incomplete, 22 Accacia, York, England
Missing End, 10 Bond Street, London

我为什么要这个?部分是因为我想不出一种方法来做到这一点,但“感觉”应该有一种方法可以得到我想要的,部分是因为这个查询是通过链接服务器运行到 SQL 2000 框的,所以我不能使用CTE(尽管我可以使用子查询轻松重写查询)。

4

2 回答 2

12

使用coalesce,例如:

WITH Addresses AS
(
SELECT
  coalesce(Name, '') + 
  coalesce(', ' + Line1, '') + 
  coalesce(', ' + Line2, '') + 
  coalesce(', ' + Line3, '') + 
  coalesce(', ' + City, '') + 
  coalesce(', ' + Country, '') AS [Address]
FROM
    @Address)
SELECT Address FROM Addresses

这将返回第一个不为 null 的参数,例如如果Line1为 null,则将返回 ''(否则,Line1)。

请注意,要使其正常工作,CONCAT_NULL_YIELDS_NULL必须设置为ON.

测试数据的结果:

Complete, Test 1, Test 2, Test 3, Oxford, England
Incomplete, 22 Accacia, York, England
Missing End, 10 Bond Street, London
于 2013-06-03T17:10:50.487 回答
4

我在这里做了几件事。首先,我用来ISNULL确定该值是否是NULL,如果是,则返回一个''(空字符串)。在测试之前,我将', '作为分隔符添加到值中以查看它是否NULL存在。这样,如果列为空,那么列+分隔符也是NULL,并且ISNULL测试仍然返回一个''. 我将分隔符放在列值之前,以便更轻松地删除额外的分隔符。如果额外的分隔符位于字符串的末尾,那么我将不得不使用一个LEN函数或类似的东西来计算额外的分隔符在哪里。这样,它始终位于字符串的开头,并且通过使用该STUFF函数,我可以将前 2 个字符替换为''有效地删除它们。

DECLARE @Address TABLE (
    Name VARCHAR(255),
    Line1 VARCHAR(255),
    Line2 VARCHAR(255),
    Line3 VARCHAR(255),
    City VARCHAR(255),
    Country VARCHAR(255));
INSERT INTO @Address VALUES ('Complete', 'Test 1', 'Test 2', 'Test 3', 'Oxford', 'England');
INSERT INTO @Address VALUES ('Incomplete', '22 Accacia', NULL, NULL, 'York', 'England');
INSERT INTO @Address VALUES ('Missing End', '10 Bond Street', NULL, NULL, 'London', NULL);

SELECT STUFF(
        ISNULL(', '+Name,'') + ISNULL(', '+Line1,'') + ISNULL(', '+Line2,'') + 
        ISNULL(', '+Line3,'') + ISNULL(', '+City,'') + ISNULL(', '+Country,'')
    ,1,2,'')
FROM @Address
于 2013-06-03T17:26:17.063 回答