MySQL CONCAT zwraca NULL, jeśli którekolwiek pole zawiera NULL

163

Mam następujące dane w mojej tabeli „urządzenia”

affiliate_name  affiliate_location  model     ip             os_type    os_version 

cs1             inter               Dell     10.125.103.25   Linux      Fedora  
cs2             inter               Dell     10.125.103.26   Linux      Fedora  
cs3             inter               Dell     10.125.103.27   NULL       NULL    
cs4             inter               Dell     10.125.103.28   NULL       NULL    

Wykonałem poniższe zapytanie

SELECT CONCAT(`affiliate_name`,'-',`model`,'-',`ip`,'-',`os_type`,'-',`os_version`) AS device_name
FROM devices

Zwraca wynik podany poniżej

cs1-Dell-10.125.103.25-Linux-Fedora
cs2-Dell-10.125.103.26-Linux-Fedora
(NULL)
(NULL)

Jak z tego wyjść, żeby ignorował NULL, a wynik powinien być

cs1-Dell-10.125.103.25-Linux-Fedora
cs2-Dell-10.125.103.26-Linux-Fedora
cs3-Dell-10.125.103.27-
cs4-Dell-10.125.103.28-
neeraj
źródło

Odpowiedzi:

279

przekonwertuj NULLwartości z pustym ciągiem, zawijając goCOALESCE

SELECT CONCAT(COALESCE(`affiliate_name`,''),'-',COALESCE(`model`,''),'-',COALESCE(`ip`,''),'-',COALESCE(`os_type`,''),'-',COALESCE(`os_version`,'')) AS device_name
FROM devices
John Woo
źródło
1
Możesz użyć, jeśli wybierz CONCAT (if (nazwa_powiązanego jest null, '', nazwa_powiązanego), '-', jeśli (model jest null, '',
nazwa_powiązanego
6
Dla tych, którzy zastanawiają się, tak jak ja, co COALESCErobi funkcja: zwraca pierwszy NULLprzekazany jej parametr niebędący wartością (lub NULLczy wszystkie parametry są NULL). Przekazując pusty ciąg jako drugi parametr, gwarantujesz, że nie zwróci NULL.
Jo.
3
MySQL IFNULL (arg, domyślnie) zamiast COALESCE z tej samej składni
Wasyl Suricov
126

Zamiast tego użyj CONCAT_WS :

CONCAT_WS () nie pomija pustych ciągów. Jednak pomija wszystkie wartości NULL po argumencie separatora.

SELECT CONCAT_WS('-',`affiliate_name`,`model`,`ip`,`os_type`,`os_version`) AS device_name FROM devices
Gurmeet
źródło
Przepraszam, neeraj przegapiłem '_' między Concat i WS Spróbuj ponownie z CONCAT_WS (). Zaktualizowałem odpowiedź, sprawdź,
Gurmeet Kwietnia
8
Zauważ, że to rozwiązanie powoduje ukrycie całej „kolumny” (łącznie z separatorem), jeśli jedno ze środkowych pól ma wartość NULL. Tak więc ta odpowiedź jest poprawna tylko przy założeniu, że tylko ostatnie pola mogą mieć wartość NULL. W zależności od potrzeb poniższa odpowiedź COALEASE () może być lepsza.
Jannes
Działa to tylko wtedy, gdy chcesz, aby każdy element członkowski był oddzielony tym samym separatorem. CONCAT nie ma tego ograniczenia. W odpowiedzi zamieściłem rozwiązanie
patrick
12

Aby mieć taką samą elastyczność w CONCAT_WS, jak w CONCAT (jeśli na przykład nie chcesz, aby ten sam separator między wszystkimi członami) był następujący:

SELECT CONCAT_WS("",affiliate_name,':',model,'-',ip,... etc)
patrick
źródło
11
SELECT CONCAT(isnull(`affiliate_name`,''),'-',isnull(`model`,''),'-',isnull(`ip`,''),'-',isnull(`os_type`,''),'-',isnull(`os_version`,'')) AS device_name
FROM devices
Harshil
źródło
15
w mysql IFNULL () zamiast ISNULL ()
Jeffrey Nicholson Carré
10

CONCAT_WSnadal daje mi wartość null, jeśli pierwsze pole ma wartość Null. Rozwiązałem to, dodając ciąg o zerowej długości na początku, jak w

CONCAT_WS("",`affiliate_name`,'-',`model`,'-',`ip`,'-',`os_type`,'-',`os_version`)

jednak

CONCAT("",`affiliate_name`,'-',`model`,'-',`ip`,'-',`os_type`,'-',`os_version`) 

daje wartość Null, gdy pierwsze pole ma wartość Null.

Ken4Edge
źródło
oczywiście, ponieważ pierwsze pole jest ciągiem, z którym będzie się łączyć (WS = with string)
Bouke Versteegh,
2
CONCAT_WS jest skrótem od Concatenate With Separator. Pierwszy parametr jest separatorem i nie może mieć wartości null. Prawdopodobnie tego chcesz zamiast tego:CONCAT_WS("-", affiliate_name, model, ip, os_type, os_version)
bój
2

możesz użyć instrukcji if, jak poniżej

select CONCAT(if(affiliate_name is null ,'',affiliate_name),'- ',if(model is null ,'',affiliate_name)) as model from devices
Dinesh Rabara
źródło