假设我在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
如何获取查询结果,以便该位置是由“,”分隔的城市,省和国家的串联,省略空值。我想确保没有任何尾随逗号,前面的逗号或空字符串。例如:
Id Location
1 Vancouver, British Columbia, Canada
2 New York
3 Adama
4 France
5 Winnepeg, Manitoba
6 Quebec, Canada
7 Seattle, USA
答案 0 :(得分:36)
我认为这可以解决我在其他答案中发现的所有问题。无需测试输出的长度或检查前导字符是否为逗号,不用担心连接非字符串类型,当其他列(例如邮政编码)不可避免地添加时,复杂性没有显着增加......
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添加了一个名为CONCAT
的新T-SQL函数,但它在这里没用,因为你仍然必须在发现的值之间包含逗号,并且没有任何工具可以做到 - 它只是munges值,没有分隔符的选项。这样可以避免担心非字符串类型,但不允许您非常优雅地处理空值与非空值。
答案 1 :(得分:10)
select Id ,
Coalesce( City + ',' +Province + ',' + Country,
City+ ',' + Province,
Province + ',' + Country,
City+ ',' + Country,
City,
Province,
Country
) as location
from table
答案 2 :(得分:3)
这是一个难题,因为逗号必须介于两者之间:
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
如果没有很多中间逻辑,我认为最简单的方法是为每个元素添加一个逗号,然后在最后删除任何无关的逗号。
答案 3 :(得分:2)
使用'+'运算符。
理解空值不适用于'+'运算符(例如:'Winnepeg'+ null = null),因此请务必使用ISNULL()或COALESCE()函数将空值替换为空值空字符串,例如:ISNULL('Winnepeg','')+ ISNULL(null,'')。
此外,如果甚至可能将一个collumns解释为数字,那么一定要使用CAST()函数,以避免错误返回,例如:CAST('Winnepeg' as varchar(100))。
到目前为止,大多数例子忽略了其中的一个或多个部分。此外 - 一些示例使用子查询或进行长度检查,您真的不应该这样做 - 只是没有必要 - 尽管如果您这样做,优化器可能会保存您。
祝你好运
答案 4 :(得分:1)
丑陋但它适用于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
答案 5 :(得分:-1)
这是一个选项:
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