MySQL selecione onde a coluna não está vazia

182

No MySQL, posso selecionar colunas apenas onde algo existe?

Por exemplo, eu tenho a seguinte consulta:

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

Estou tentando selecionar apenas as linhas em que o telefone começa com 813 e o phone2 tem algo.

Mike
fonte
2
Você pode esclarecer o que você quer dizer com " phone2tem algo nele"? As pessoas estão tomando suposições quanto a saber se você quer dizer phone2não é nulo, não estiver em branco, se não exclusivamente espaços em branco, etc.
Pilcrow
1
se "algo" existe, obviamente não é nulo.
Mike8 /

Respostas:

277

Compare o valor de phone2com uma sequência vazia:

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

Observe que o NULLvalor é interpretado como false.

Ivan Nevostruev
fonte
5
Aspas simples, não as aspas duplas.
OMG Ponies
2
phone2<>""não deixará passar nenhum verificador de sintaxe SQL.
OMG Ponies
5
Pôneis @ OMG: Mas funciona no mysql. Este é o único verificador importante
Ivan Nevostruev
7
@ivan: Notícias para mim, desculpe por isso.
OMG Ponies
<> é o mesmo que! =. foi simples. mas eu não sabia :)
MFarooqi
48

Para verificar se o campo é NULL IS NULL, use IS NOT NULLoperadores.

Referência do MySql http://dev.mysql.com/doc/refman/5.0/en/working-with-null.html

Stanislav Stoyanov
fonte
10
O OP está perguntando apenas sobre as linhas que possuem algo no campo phone2. IS NOT NULL retorna tudo o que literalmente não está definido como NULL, mesmo a string vazia "". ! = '' ou <> '', como Ivan disse na resposta aceita, não retornará cadeias vazias ou valores NULL. Em outras palavras, IS NOT NULL é um subconjunto de! = '', Mas eles não são equivalentes.
Nenhum
34

Verifique NULLe esvazie os valores das strings:

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

NB: Acho que COALESCE () é o padrão SQL (-ish), enquanto ISNULL () não é.

davek
fonte
1
Você não precisa usar a função trim, uma vez que no MySQL uma string de qualquer número de espaços é igual a outra string de qualquer número de espaços, escrevi em resposta sobre isso com bastante detalhes stackoverflow.com/a/ 42723975/728236
Brian Leishman
26

Uma resposta que eu tenho usado e que está funcionando muito bem para mim que eu ainda não vi aqui (essa pergunta é muito antiga, então pode não ter funcionado) é realmente

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

Observe o > '' parte, que verificará se o valor não é nulo e se o valor não é apenas espaço em branco ou em branco.

Basicamente, se o campo tiver algo diferente de espaço em branco ou NULL, é verdade. Também é super curto, por isso é fácil de escrever, e outra vantagem sobre COALESCE()eIFNULL() funções é que isso é amigável ao índice, pois você não está comparando a saída de uma função em um campo a nada.

Casos de teste:

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

ATUALIZAÇÃO Há uma ressalva que eu não esperava, mas os valores numéricos iguais ou inferiores a zero não são maiores que uma string em branco; portanto, se você estiver lidando com números que podem ser zero ou negativos, NÃO FAÇA ISSO , me mordeu muito recentemente e foi muito difícil depurar :(

Se você estiver usando strings (char, varchar, texto etc.), tudo ficará perfeitamente bem, mas tenha cuidado com os números.

Brian Leishman
fonte
17

Se houver espaços no campo phone2 a partir da entrada de dados inadvertida, você poderá ignorar esses registros com as funções IFNULL e TRIM:

SELECT phone, phone2
FROM jewishyellow.users
WHERE phone LIKE '813%'
    AND TRIM(IFNULL(phone2,'')) <> '';
micahwittman
fonte
Você não precisa usar a função trim, uma vez que no MySQL uma string com qualquer número de espaços é igual a outra string com qualquer número de espaços, escrevi em resposta sobre isso com bastante detalhes stackoverflow.com/a/ 42723975/728236
Brian Leishman
7
select phone, phone2 from jewishyellow.users 
where phone like '813%' and phone2 is not null
Klaus Byskov Pedersen
fonte
6
Observe que há uma diferença entre um NULLvalor e uma string vazia ''que é um valor. Se você deseja verificar uma sequência vazia, use column <> ''como sugerido pelas outras respostas.
Dzhuneyt 31/07/2013
7
SELECT phone, phone2 
FROM jewishyellow.users 
WHERE phone like '813%' and (phone2 <> "");

Pode precisar de alguns ajustes, dependendo do seu valor padrão. Se você permitiu o preenchimento Nulo, pode fazer "Não NULL", o que é obviamente melhor.

Satanicpuppy
fonte
Não vou anotá-lo, mas: 1) Não há NOT()função no MySQL 2) phone2=""não passará por nenhum verificador de sintaxe SQL.
OMG Ponies
1
Heh, desculpe. Eu uso muitos servidores SQL diferentes.
8789 Satanicpuppy
2

Podemos usar CASE para definir o valor em branco para algum caractere ou String. Estou usando NA como string padrão.

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

Outra alternativa é examinar especificamente CHAR_LENGTHos valores da coluna. (para não confundir LENGTH)

O uso de critérios em que o tamanho do caractere seja maior que 0 evitará falsos positivos quando os valores da coluna puderem ser falsos, como no caso de uma coluna inteira com um valor de 0ouNULL . Comportando-se de forma mais consistente em diferentes tipos de dados.

O que resulta em qualquer valor que tenha pelo menos 1 caractere ou não esteja vazio.

Exemplo https://www.db-fiddle.com/f/iQvEhY1SH6wfruAvnmWdj5/1

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

Dados da tabela

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) > 0Resultados (o mesmo)

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

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

Alternativas

phone2 <> ''Resultados (diferentes)

users
813-123-4567       | 1

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

phone2 > ''Resultados (diferentes)

users
813-123-4567       | 1

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

COALESCE(phone2, '') <> ''Resultados (o mesmo)
Nota: os resultados diferem dos phone2 IS NOT NULL AND phone2 <> ''que não são esperados

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

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

phone2 IS NOT NULL AND phone2 <> ''Resultados (diferentes)

users
813-123-4567       | 1

users2
813-123-4567       | 1
813-123-4567       | 0
fyrye
fonte
2

Surpreendentemente (como ninguém mencionou antes), constatou que a condição abaixo faz o trabalho:

WHERE ORD(field_to_check) > 0 

quando precisamos excluir valores nulos e vazios. Alguém está ciente das desvantagens da abordagem?

Sergey Ch
fonte
Eu tenho tentado por horas para obter a sintaxe correta e isso resolveu tudo, obrigado!
demo7up 3/07
1

Usar:

SELECT t.phone, 
       t.phone2 
  FROM jewishyellow.users t
 WHERE t.phone LIKE '813%' 
   AND t.phone2 IS NOT NULL
Pôneis OMG
fonte
1
Notei que, às vezes, IS NOT NULLnão é aplicado a cadeias apenas de colunas com valores vazios ( ''). Não sei por que, mas só queria salientar. É mais sábio usar t.phone2 <> ''ao procurar colunas de string vazias.
Dzhuneyt
0

você pode usar como curinga do operador para conseguir isso:

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

Dessa forma, você pode obter todos os telefones2 que tenham um prefixo de número.

Panda
fonte
0

No meu caso, eu tinha uma coluna varchar, ambos os métodos de IS NOT NULL& != '' não funcionaram , mas o seguinte funcionou para mim. Apenas colocando isso aqui.

SELECT * FROM `db_name` WHERE `column_name` LIKE '%*%'
Mohd Abdul Mujib
fonte