В SQL: конкатенация значений столбцов в одной строке в строку через запятую
предположим, у меня есть такая таблица в 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
6 ответов
Я думаю, что это позаботится обо всех проблемах, которые я заметил в других ответах. Нет необходимости проверять длину вывода или проверять, является ли ведущий символ запятой, не беспокоиться о конкатенации нестроковых типов, не значительно усложняется, когда неизбежно добавляются другие столбцы (например, почтовый индекс)...
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
, но это не полезно здесь, так как вы все равно должны дополнительно включать запятые между обнаруженными значениями, и нет возможности сделать это - он просто munges значения вместе без опции для разделителя. Это позволяет избежать необходимости беспокоиться о нестроковых типах, но не позволяет обрабатывать нули против не-нулей очень элегантно.
select Id ,
Coalesce( City + ',' +Province + ',' + Country,
City+ ',' + Province,
Province + ',' + Country,
City+ ',' + Country,
City,
Province,
Country
) as location
from table
это сложная проблема, потому что запятые должны идти между:
select id, coalesce(city+', ', '')+coalesce(province+', ', '')+coalesce(country, '')
from t
Кажется, что это должно работать, но мы можем получить постороннюю запятую в конце, например, когда страна равна нулю. Итак, это должно быть немного сложнее:
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
без большой промежуточной логики я думаю, что самый простой способ-добавить запятую к каждому элементу, а затем удалить любую постороннюю запятую в конце.
использовать оператор'+'.
поймите, что значения null не работают с оператором ' + '(например:' Winnepeg' + null = null), поэтому обязательно используйте функции ISNULL () или COALESCE () для замены нулей пустой строкой, например: ISNULL ('Winnepeg',") + ISNULL (null,").
кроме того, если даже отдаленно возможно, что один из ваших collumns может быть интерпретирован как число, то обязательно используйте функцию CAST (), чтобы избежать возврата ошибок, например: В ролях ('Winnepeg' as varchar (100)).
большинство примеров до сих пор пренебрегают одной или несколькими частями этого. Кроме того, некоторые примеры используют подзапросы или выполняют проверку длины, что вам действительно не следует делать-просто не нужно-хотя ваш оптимизатор может спасти вас в любом случае, если вы это сделаете.
Удачи
некрасиво, но это будет работать для 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
вот такой вариант:
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