MySQL wybierz, gdzie kolumna nie jest pusta


182

Czy w MySQL mogę wybierać kolumny tylko tam, gdzie coś istnieje?

Na przykład mam następujące zapytanie:

select phone, phone2
from jewishyellow.users
where phone like '813%'
and phone2

Próbuję wybrać tylko wiersze, w których telefon zaczyna się od 813, a phone2 ma coś w sobie.


2
Czy możesz wyjaśnić, co rozumiesz przez „ phone2coś w tym jest?” Ludzie phone2
zgadują,

1
jeśli „coś” istnieje, to oczywiście nie jest zerowe.
Mike

Odpowiedzi:


277

Porównaj wartość phone2z pustym ciągiem:

select phone, phone2 
from jewishyellow.users 
where phone like '813%' and phone2<>''

Zauważ, że NULLwartość jest interpretowana jako false.


5
Pojedyncze cudzysłowy, a nie podwójne.
OMG Ponies

2
phone2<>""nie przejdzie przez żaden moduł sprawdzania składni SQL.
Kucyki OMG,

5
@OMG Kucyki: Ale działa w mysql. To jedyny sprawdzający, który ma znaczenie
Ivan Nevostruev

7
@ivan: Wiadomość do mnie, przepraszam za to.
OMG Ponies

<> jest taki sam jak! =. to było proste. ale nie wiedziałem :)
MFarooqi

48

Aby sprawdzić, czy pole ma wartość NULL IS NULL, IS NOT NULLoperatory.

Referencje MySql http://dev.mysql.com/doc/refman/5.0/en/working-with-null.html


10
OP pyta tylko o wiersze, które mają coś w polu phone2. IS NOT NULL zwraca wszystko, co dosłownie nie jest ustawione na NULL, nawet pusty ciąg „”. ! = '' lub <> '', jak powiedział Ivan w przyjętej odpowiedzi, nie zwróci pustych ciągów ani wartości NULL. Innymi słowy IS NOT NULL jest podzbiorem! = '', Ale nie są równoważne.
Brak,

34

Sprawdź NULLi opróżnij wartości ciągu:

select phone
, phone2 
from users 
where phone like '813%' 
and trim(coalesce(phone2, '')) <>''

NB: Myślę, że COALESCE () jest standardem SQL (-ish), podczas gdy ISNULL () nie.


1
Nie musisz używać funkcji przycinania, ponieważ w MySQL ciąg dowolnej liczby spacji jest równy innym ciągom dowolnej liczby spacji, w odpowiedzi na to napisałem dość szczegółowo stackoverflow.com/a/ 42723975/728236
Brian Leishman,

26

Odpowiedź, z której korzystam, która działa dla mnie całkiem dobrze, której jeszcze nie widziałem (to pytanie jest bardzo stare, więc mogło wtedy nie zadziałać) jest w rzeczywistości

SELECT t.phone, 
       t.phone2 
  FROM jewishyellow.users t
 WHERE t.phone LIKE '813%' 
   AND t.phone2 > ''

Zwróć uwagę na > ''część, która sprawdzi, czy wartość nie jest pusta, i czy wartość nie jest tylko białą spacją lub pustą.

Zasadniczo, jeśli pole zawiera coś innego niż białe znaki lub NULL, to prawda. Jest również bardzo krótki, więc łatwo go pisać, a dodatkowym plusem w stosunku do funkcji COALESCE()i IFNULL()jest to, że jest przyjazny dla indeksu, ponieważ nie porównujesz wyników funkcji w polu z niczym.

Przypadki testowe:

SELECT if(NULL > '','true','false');-- false
SELECT if('' > '','true','false');-- false
SELECT if(' ' > '','true','false');-- false
SELECT if('\n' > '','true','false');-- false
SELECT if('\t' > '','true','false');-- false
SELECT if('Yeet' > '','true','false');-- true

AKTUALIZACJA Istnieje zastrzeżenie, którego się nie spodziewałem, ale wartości liczbowe, które są zerowe lub niższe, nie są większe niż pusty ciąg znaków, więc jeśli masz do czynienia z liczbami, które mogą być zerowe lub ujemne, NIE Rób tego , ugryzł mnie bardzo niedawno i bardzo trudno było go debugować :(

Jeśli używasz ciągów znaków (char, varchar, text itp.), Będzie to w porządku, po prostu bądź ostrożny z liczbami.


17

Jeśli w polu phone2 znajdują się spacje przed przypadkowym wprowadzeniem danych, możesz zignorować te rekordy za pomocą funkcji IFNULL i TRIM:

SELECT phone, phone2
FROM jewishyellow.users
WHERE phone LIKE '813%'
    AND TRIM(IFNULL(phone2,'')) <> '';

Nie musisz używać funkcji przycinania, ponieważ w MySQL ciąg dowolnej liczby spacji jest równy innym ciągom dowolnej liczby spacji, w odpowiedzi na to napisałem dość szczegółowo stackoverflow.com/a/ 42723975/728236
Brian Leishman,

7
select phone, phone2 from jewishyellow.users 
where phone like '813%' and phone2 is not null

6
Zauważ, że istnieje różnica między NULLwartością a pustym ciągiem, ''który jest wartością. Jeśli chcesz sprawdzić pusty ciąg, użyj column <> ''zgodnie z sugestiami innych odpowiedzi.
Dzhuneyt

7
SELECT phone, phone2 
FROM jewishyellow.users 
WHERE phone like '813%' and (phone2 <> "");

Może wymagać drobnych poprawek w zależności od domyślnej wartości. Jeśli zezwoliłeś na wypełnienie zerowe, możesz zamiast tego zrobić „Nie NULL”, co jest oczywiście lepsze.


Nie zaznaczę cię, ale: 1) W NOT()MySQL 2 phone2=""nie ma funkcji) nie przejdzie przez żaden moduł sprawdzania składni SQL.
Kucyki OMG,

1
Heh przepraszam Używam wielu różnych serwerów SQL.
Satanicpuppy

2

Możemy użyć CASE do ustawienia pustej wartości na char lub String. Używam NA jako ciągu domyślnego.

SELECT phone,   
CASE WHEN phone2 = '' THEN 'NA' END AS phone2 ELSE ISNULL(phone2,0) 
FROM jewishyellow.users  WHERE phone LIKE '813%'

2

Inną alternatywą jest przyjrzenie się konkretnie CHAR_LENGTHwartościom kolumny. (nie mylić z LENGTH)

Zastosowanie kryteriów, w których długość znaku jest większa od 0, pozwoli uniknąć fałszywych trafień, gdy wartości kolumn mogą być zmienne, na przykład w przypadku kolumny całkowitej o wartości 0lub NULL. Zachowanie bardziej spójne dla różnych typów danych.

Co powoduje, że każda wartość ma co najmniej 1 znak lub w inny sposób nie jest pusta.

Przykład https://www.db-fiddle.com/f/iQvEhY1SH6wfruAvnmWdj5/1

SELECT phone, phone2
FROM users
WHERE phone LIKE '813%'
AND CHAR_LENGTH(phone2) > 0

Dane tabeli

users
phone (varchar 12) | phone2 (int 10)
"813-123-4567"     | NULL
"813-123-4567"     | 1
"813-123-4567"     | 0

users2
phone (varchar 12) | phone2 (varchar 12)
"813-123-4567"     | NULL
"813-123-4567"     | "1"
"813-123-4567"     | "0"
"813-123-4567"     | ""

CHAR_LENGTH(phone2) > 0Wyniki (takie same)

users
813-123-4567       | 1
813-123-4567       | 0

users2
813-123-4567       | 1
813-123-4567       | 0

Alternatywy

phone2 <> ''Wyniki (różne)

users
813-123-4567       | 1

users2
813-123-4567       | 1
813-123-4567       | 0

phone2 > ''Wyniki (różne)

users
813-123-4567       | 1

users2
813-123-4567       | 1
813-123-4567       | 0

COALESCE(phone2, '') <> ''Wyniki (takie same)
Uwaga: wyniki różnią się od tych, phone2 IS NOT NULL AND phone2 <> ''których się nie oczekuje

users
813-123-4567       | 1
813-123-4567       | 0

users2
813-123-4567       | 1
813-123-4567       | 0

phone2 IS NOT NULL AND phone2 <> ''Wyniki (różne)

users
813-123-4567       | 1

users2
813-123-4567       | 1
813-123-4567       | 0

2

Zaskakująco (jak nikt wcześniej o tym nie wspominał) stwierdził, że warunek poniżej spełnia swoje zadanie:

WHERE ORD(field_to_check) > 0 

kiedy musimy wykluczyć zarówno wartości puste, jak i zerowe. Czy ktoś jest świadomy wad tego podejścia?


Próbowałem godzinami, aby uzyskać poprawną składnię, a to właśnie rozwiązało wszystko dzięki!
demo7up

1

Posługiwać się:

SELECT t.phone, 
       t.phone2 
  FROM jewishyellow.users t
 WHERE t.phone LIKE '813%' 
   AND t.phone2 IS NOT NULL

1
Zauważyłem, że czasami IS NOT NULLnie stosuje się tylko do ciągów kolumn z pustymi wartościami ( ''). Nie wiem dlaczego, ale chciałem tylko to podkreślić. Rozsądniej jest go używać t.phone2 <> ''podczas sprawdzania pustych kolumn ciągów.
Dzhuneyt,

0

w tym celu możesz użyć operatora wieloznacznego:

SELECT t.phone, 
       t.phone2 
FROM jewishyellow.users t
WHERE t.phone LIKE '813%' 
  AND t.phone2 like '[0-9]';

w ten sposób można uzyskać wszystkie phone2, które mają prefiks numeru.


0

W moim przypadku miałem kolumnę varchar, obie metody IS NOT NULL& != '' nie działały , ale następujące działały dla mnie. Po prostu to tutaj przedstawiam.

SELECT * FROM `db_name` WHERE `column_name` LIKE '%*%'
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.