Disons que j'ai une table comme celle-ci dans 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
Comment puis-je obtenir un résultat de requête afin que l'emplacement soit une concaténation de la ville, de la province et du pays séparés par ",", avec des valeurs nulles omises. Je voudrais m'assurer qu'il n'y a pas de virgule de fin, de virgule précédente ou de chaîne vide. Par exemple:
Id Location
1 Vancouver, British Columbia, Canada
2 New York
3 Adama
4 France
5 Winnepeg, Manitoba
6 Quebec, Canada
7 Seattle, USA
Je pense que cela règle tous les problèmes que j'ai repérés dans d'autres réponses. Pas besoin de tester la longueur de la sortie ou de vérifier si le premier caractère est une virgule, pas de souci de concaténation des types non-chaîne, pas d'augmentation significative de la complexité lorsque d'autres colonnes (par exemple Code Postal) sont inévitablement ajoutées ...
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 a ajouté une nouvelle fonction T-SQL appelée CONCAT
, mais elle n'est pas utile ici, car vous devez toujours inclure éventuellement des virgules entre les valeurs découvertes, et il n'y a aucune possibilité de faites cela - il ne fait que fusionner les valeurs sans aucune option pour un séparateur. Cela évite d'avoir à se soucier des types non-chaîne, mais ne vous permet pas de gérer les nulls vs non-nulls de manière très élégante.
select Id ,
Coalesce( City + ',' +Province + ',' + Country,
City+ ',' + Province,
Province + ',' + Country,
City+ ',' + Country,
City,
Province,
Country
) as location
from table
C'est un problème difficile, car les virgules doivent se situer entre les deux:
select id, coalesce(city+', ', '')+coalesce(province+', ', '')+coalesce(country, '')
from t
semble que cela devrait fonctionner, mais nous pouvons obtenir une virgule superflue à la fin, comme lorsque le pays est NULL. Donc, ça doit être un peu plus compliqué:
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
Sans beaucoup de logique intermédiaire, je pense que le moyen le plus simple est d'ajouter une virgule à chaque élément, puis de supprimer toute virgule superflue à la fin.
Utilisez l'opérateur "+".
Comprenez que les valeurs nulles ne fonctionnent pas avec l'opérateur '+' (donc par exemple: 'Winnepeg' + null = null), assurez-vous donc d'utiliser les fonctions ISNULL () ou COALESCE () pour remplacer les nulls par une chaîne vide, par exemple: ISNULL ('Winnepeg', '') + ISNULL (null, '').
De plus, s'il est même possible à distance qu'une de vos colonnes puisse être interprétée comme un nombre, assurez-vous également d'utiliser la fonction CAST (), afin d'éviter les retours d'erreur, par exemple: CAST ('Winnepeg' as varchar ( 100)).
Jusqu'à présent, la plupart des exemples en négligent un ou plusieurs éléments. De plus, certains exemples utilisent des sous-requêtes ou effectuent une vérification de la longueur, ce que vous ne devriez vraiment pas faire - tout simplement pas nécessaire - bien que votre optimiseur puisse vous sauver de toute façon si vous le faites.
Bonne chance
laid mais cela fonctionnera pour 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