MySQL - Tüm sütunlarda bir değer nasıl kontrol edilir


11

Merak ediyorum, belirli bir değer için tüm sütunları aramanın iyi bir yolu var mı? Benim amacım için, hızlı olması gerekmiyor, sadece bir kerelik bir şey ve her alan adını yazmak zorunda kalmak istemiyorum. Şimdilik yapacağım tam olarak bu, ama bence kesinlikle daha iyi bir yol var.

Bunu çevirmek istiyorum:

SELECT * FROM table WHERE col1 = 'val' OR col2 = 'val' OR col3 = 'val';

bunun içine:

SELECT * FROM table WHERE * = 'val'

... ya da daha da iyisi (ciddi olarak şüphe duymama rağmen ...)

SELECT * FROM table WHERE * like '%val%'

Bulduğum bu hangi tür-not-gerçekten yakın görünüyor, ama daha yakın bir şey bulamıyorum,:

SELECT whatever WHERE col1,col2 IN ((val1, val2), (val1, val2), ...)

Tek bir değer için TÜM sütunları aramaya çalışırken, fark, belirtilen değerler için sütun seçimi arar.

Yine de önemli değil, dediğim gibi merak ettiğim her şeyden daha fazlası

Yanıtlar:


23

SQL, bunu yapmak için iyi bir yol sağlamaz, çünkü aynı etki alanında değerleri olabilecek N sütunlara sahip olmak muhtemelen iyi bir tablo tasarımı değildir . Bu potansiyel olarak "yinelenen grupları" sütunları varsa benzeri bir durumdur phone1, phone2, phone3, ... phoneN.

Aynı mantıksal değer etki alanına sahip bir dizi sütununuz varsa, bunun çok değerli bir özellik (telefonlar örneği gibi) olduğu bir durum olabilir. Çok değerli öznitelikleri depolamanın standart yolu, birincil tabloda ait oldukları satıra referansla başka bir tabloda birden çok satır gibidir.

Bunu yaparsanız, bağımlı tablonun bir sütununda yalnızca belirli bir değeri aramanız gerekir.

SELECT t.* FROM mytable AS t
JOIN phones AS p ON t.primaryKey = p.refKey 
WHERE p.phone = ?

1
Herhangi bir nedenle tablo düzenini değiştiremiyorsanız, bu biçimdeki verileri temsil eden bir görünüm yazıp görünümü sorgulayabilirsiniz.
CodeCaster

10
Hayır, sadece tablo düzenini değiştirin. Bu kadar. "Değiştiremem" bahanesinden bıktım. Artık kabul etmiyorum. Bir şeyi nasıl değiştireceğinizi öğrenmenin zamanı geldi.
Bill Karwin

15

Yaklaşabileceğiniz şudur IN:

SELECT * FROM table WHERE 'val' IN (col1, col2, ..., colN) ;

Hala kontrol etmek istediğiniz tüm sütunları yazmanız gerekir.
Ve sahip olduğunuz ORifadeden farklı değil, performansta veya başka türlü değil. Bu, ifadeyi yazmanın biraz daha az karakterle farklı, eşdeğer bir yoludur.


3

Bunu iki adımda yapmanız gerekir, önce sql'yi oluşturun (tablonuzun S şemasında T olarak adlandırıldığı varsayılarak:

select concat(' SELECT * FROM t WHERE ''a'' in ('
             , GROUP_CONCAT(COLUMN_NAME)
             , ')')
from INFORMATION_SCHEMA.columns 
where table_schema = 's' 
  and table_name = 't'
  and DATA_TYPE IN ('char','varchar');

Şimdi bu dizeyi yürütebilirsiniz. 'A' ile ekstra 'alıntı yapmanız gerektiğini unutmayın. Bunu örneğin bir yordama koyarsanız, oluşturulan dizeyi hazırlayabilir ve yürütebilirsiniz.

Şununla test ettim:

create table t (a char(3), b varchar(5), c int);
insert into t(a,b) values ('a','b'),('b','c'),('c','c');    

Oluşturulan sorgu nerede:

SELECT * FROM t WHERE 'a' in (a,b)

ve bunun sonucu:

a   b   c
---------
a   b   

1

Bunu sorduğumdan bu yana bir yıl geçti, ama tam aradığım şey gibi görünüyordu! Beklediğim gibi bir SQL ifadesi değil, ama istediğimi yapıyor.

MySQL Workbench'te, tabloyu veya şemayı sağ tıklatıp Tablo Verilerini Ara'yı seçebilirsiniz.şema bağlam menüsü


0

Bunu dene:

select
    *
from
    _table_
where
    concat('.', col1, '.', col2, '.', col3, '.') like "%.search_value.%";

Bu ., arama dizenizde hayır olmadığını varsayar . Bunu garanti edemezseniz, belki farklı bir “ayırıcı karakter” kullanabilirsiniz.


1
Çözümünüzün neden işe yaradığını açıklar mısınız? Burada yalnızca kod yanıtları iyi bir yanıt olarak görülmez.
George.Palacios

çalışmıyor. örneğin te arama içeriyorsa %veya _herhangi bir sütun içeriyorsa.
Jasen

1
@Jasen Özel karakterlerden kaçabilir ve farklı bir ayırıcı kullanabilirsiniz.
Anon0012398193

@ George.Palacios - belirsiz bulduğunuz nedir?
Anon0012398193

doğru ayırıcıyı seçmek çok zor olabilir. bu yaklaşım doğru yapmak çok zor
Jasen

0

En basit çözüm

mysqldump ... --skip-extended-insert db table | grep 'val'

Val , sql sözdiziminde sık karşılaşılan bir şey olmadığı sürece .


Umarım benimle alay ediyorsun, alternatif olarak bunun yararlı olacağını düşünüyorsun.
donutguy640

1
Ben kesinlikle değilim. Eğer db / tablosunda "nerede" bilmiyorsanız bir şey bulmak için geçerli bir yoludur. Grep, değerin bulunduğu tüm satırları (tablo adı dahil) döndürür. SQL değildir ve çıktıyı programlı olarak işlemek istiyorsanız çok kullanışlı değildir, ancak basit ve oldukça hızlıdır.
jkavalik

-2

Bunu dene.

SELECT *
FROM table
WHERE CONCAT(col1,' ',col2,' ',col3)="val val val";

CONCAT (), burada olduğu gibi sütun değerlerini ayırmak için kullanılır, işlev içinde daha iyi sonuç belirtmek için sütununuzu boşlukla ayırabilir ve ayrıca boşlukla ayrılmış dizeyi de kontrol edebilirsiniz ve sonuç elinizde.


-3

İnformation_schema veritabanını kullanarak, sadece belirli bir tablonun tüm sütunlarını listeleyeceğiz, sonra bunları bir satır olarak listelemek için GROUP_CONCAT kullanacağız ve bir IN deyimiyle besleyeceğiz.

select * from db.table where 'value' in (select GROUP_CONCAT(COLUMN_NAME) from INFORMATION_SCHEMA.columns where table_schema = 'db' and table_name = 'table');

Bu, yalnızca tüm sütunlarda 'değer' varsa bir satır döndürür.


1
Bunu mu demek istediniz if 'value' is present in any of the columns? `Ve DATA_TYPE IN ( 'karakter', 'varchar')`: Ayrıca, gibi dize türleri için bir yüklemi ekleyebilir
Lennart

1
Bunu yapar ve OP'nin sütunları açıkça adlandırmaktan kaçınma hedefini gerçekleştirir. Bir joker karakter değildir, ancak bilgi şemasına karşı GROUP_CONCAT tüm sütun adlarının joker karakteri kadar iyidir.
tbrookside

2
Bunu işe almakta zorlanıyorum. Db ve tabloyu şema ve tablo isimlerimle değiştirdim, gerçek isimler için yer tutucu olması amaçlanan başka bir şey var mı? Ayrıca, iç ifadeyi kendi başına denedim ve bir satırın verileri yerine sütun adlarını CONCAT ettiğini fark ediyorum. İstediğin bu mu?
donutguy640

4
Saygılarımızla, bu yanlış. Sorgunuz ' değer'i içerikleriyle değil sütun adlarıyla karşılaştırır . Bunu aşağıya vermek zorundayım.
Bill Karwin

4
Daha doğru bir şekilde, bu, 'değer' dizesini, sütun adlarının virgülle ayrılmış bir listesi olan - esas olarak aynı olan dizeyle karşılaştıracaktır where 'value' in ('col1,col2,col3…').
Andriy M
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.