SQL Server SQL:将单行中的列值连接成一个由逗号分隔的字符串

fcwjkofz  于 2023-01-08  发布在  其他
关注(0)|答案(7)|浏览(228)

假设我在SQL Server中有这样一个表:

Id    City           Province             Country
1     Vancouver      British Columbia     Canada
2     New York       null                 null
3     null           Adama                null
4     null           null                 France
5     Winnepeg       Manitoba             null
6     null           Quebec               Canada
7     Seattle        null                 USA

如何获取查询结果,以便位置是由“,“分隔的City、Province和Country的串联,并省略null。我希望确保没有任何尾随逗号、前导逗号或空字符串。例如:

Id    Location
1     Vancouver, British Columbia, Canada
2     New York
3     Adama
4     France
5     Winnepeg, Manitoba
6     Quebec, Canada
7     Seattle, USA
mnemlml8

mnemlml81#

我认为这解决了我在其他答案中发现的所有问题:无需测试输出的长度或检查前导字符是否为逗号,无需担心连接非字符串类型,当不可避免地添加其他列(例如邮政编码)时,不会显著增加复杂性. a....

DECLARE @x TABLE(Id INT, City VARCHAR(32), Province VARCHAR(32), Country VARCHAR(32));

INSERT @x(Id, City, Province, Country) VALUES
(1,'Vancouver','British Columbia','Canada'),
(2,'New York' , null             , null   ),
(3, null      ,'Adama'           , null   ),
(4, null      , null             ,'France'),
(5,'Winnepeg' ,'Manitoba'        , null   ),
(6, null      ,'Quebec'          ,'Canada'),
(7,'Seattle'  , null             ,'USA'   );

SELECT Id, Location = STUFF(
      COALESCE(', ' + RTRIM(City),     '') 
    + COALESCE(', ' + RTRIM(Province), '') 
    + COALESCE(', ' + RTRIM(Country),  '')
    , 1, 2, '')
  FROM @x;

SQL Server 2012添加了一个新的T-SQL函数CONCAT,但它在这里没有用,因为你仍然必须在发现的值之间选择性地包含逗号,而且没有工具来完成这一点-它只是将值合并在一起,没有分隔符选项。这避免了担心非字符串类型,但不允许你非常优雅地处理空值与非空值。

ufj5ltwl

ufj5ltwl2#

select Id ,   
 Coalesce( City + ',' +Province + ',' + Country,
           City+ ',' + Province,
           Province + ',' + Country,
           City+ ',' + Country,
           City,
           Province,
           Country
          ) as location
from table
dm7nw8vv

dm7nw8vv3#

这是一个难题,因为逗号必须放在中间:

select id, coalesce(city+', ', '')+coalesce(province+', ', '')+coalesce(country, '')
from t

看起来应该可以,但是我们可能会在结尾处得到一个无关的逗号,比如当country为NULL时。所以,它需要稍微复杂一点:

select id,
       (case when right(val, 2) = ', ' then left(val, len(val) - 1)
             else val
        end) as val
from (select id, coalesce(city+', ', '')+coalesce(province+', ', '')+coalesce(country, '') as val
      from t
     ) t

在没有很多中间逻辑的情况下,我认为最简单的方法是给每个元素添加一个逗号,然后删除结尾处任何无关的逗号。

qv7cva1a

qv7cva1a4#

使用"+"运算符。
了解空值不适用于"+"运算符(例如:'Winnepeg'+ null = null),因此请确保使用ISNULL()或COALESCE()函数将null替换为空字符串,例如:ISNULL("温尼伯","")+ISNULL(空值,"")。
此外,如果您的列中有一列可能被解释为数字,那么请确保也使用CAST()函数,以避免返回错误,例如:CAST("温尼伯"为varchar(100))。
到目前为止,大多数例子忽略了其中的一个或多个部分,还有--一些例子使用子查询或进行长度检查,这是你真的不应该做的--只是没有必要--尽管如果你这样做了,你的优化器可能会拯救你。
祝你好运

fjaof16o

fjaof16o5#

丑陋,但它将工作的MS SQL:

select
    id,
    case
        when right(rtrim(coalesce(city + ', ','') + coalesce(province + ', ','') + coalesce(country,'')),1)=',' then left(rtrim(coalesce(city + ', ','') + coalesce(province + ', ','') + coalesce(country,'')),LEN(rtrim(coalesce(city + ', ','') + coalesce(province + ', ','') + coalesce(country,'')))-1)
        else rtrim(coalesce(city + ', ','') + coalesce(province + ', ','') + coalesce(country,''))
    end
from
    table
ws51t4hk

ws51t4hk6#

我知道这是一个老问题,但如果有人今天偶然发现这个问题,SQL Server 2017及更高版本提供了STRING_AGG函数,带有WITHIN GROUP选项:

with level1 as
(select id,city as varcharColumn,1 as columnRanking from mytable
union
select id,province,2 from mytable
union
select id,country,3 from mytable)
select STRING_AGG(varcharColumn,', ')
within group(order by columnRanking)
from level1
group by id

如果空字符串存在于空值之外,则应使用level1中的WHERE子句将其排除。

fdx2calv

fdx2calv7#

下面是一个选项:

SELECT (CASE WHEN City IS NULL THEN '' ELSE City + ', ' END) + 
(CASE WHEN Province IS NULL THEN '' ELSE Province + ', ' END) +
(CASE WHEN Country IS NULL THEN '' ELSE Country END) AS LOCATION
FROM MYTABLE

相关问题