2012-04-05 17 views
13

W jaki sposób używałbyś "LIKE" do wyszukiwania w podkwerendie?MYSQL używa "LIKE" w klauzuli "WHERE" do wyszukiwania w podkwerendie

E.g. Próbowałem to zrobić, ale nie działa:

SELECT * 
FROM mytable 
WHERE name 
    LIKE '% 
     (SELECT name FROM myothertable) 
     %' 

mam to do tej pory:

SELECT * FROM t1 
WHERE t1.name IN (SELECT t2.name FROM t2) 
AND (t1.title IN (SELECT t2.title FROM t2) 
    OR t1.surname IN (SELECT t2.surname FROM t2)) 

To działa ok, to zwraca dokładny matchs, ale to nie robi wydaje się na moje inne zapisy, które są podobne, więc chciałbym również sprawdzić, czy:

t1.title LIKE '%' % t2.title I t1.surname LIKE '%' % t2.surname

Jak robię to s?

+0

Ile rzędów ma twój "myothertable"? – zerkms

+0

tylko dwie małe poprawki w kodzie. 1. Usuń% i like.Second dodać po nazwie, pełny kod jest w mojej odpowiedzi. –

+0

DZIĘKUJEMY WSZYSTKIM ZA SWOJE ODPOWIEDZIALNE ODPOWIEDZI^^^^. @zerkms - około 10, ale to naprawdę nie wpływa na to, co próbuję zrobić, chcę tylko porównać kilka pól. – qwerty

Odpowiedz

11

Na przykład

SELECT a_column 
FROM mytable t 
WHERE EXISTS (
      SELECT 1 
      FROM myothertable ot 
      WHERE t.`name` LIKE '%' || ot.`name` || '%'); 

ile terminologia przechodzi: jest to znane jako skorelowanej podzapytaniu.

+1

A jeśli pójdziemy dalej - każde podzapytanie w mysql jest skorelowane ;-) (lub dokładniej: optymalizator przepisuje każde podzapytanie na skorelowane) – zerkms

+2

@zerkms: 'EXISTS' nie wykonuje się jako skorelowane podzapytanie –

+0

@OMG Kucyki: Ok, ale nie powiedziałem, że tak ;-) – zerkms

17

Korzystanie JOIN:

SELECT a.* 
    FROM mytable a 
    JOIN myothertable b ON a.name LIKE CONCAT('%', b.name, '%') 

... ale nie może być duplikatami, jeśli istnieje więcej niż jeden mecz w myothertable dla danego mytable rekordu.

Korzystanie istnieje:

SELECT a.* 
    FROM mytable a 
WHERE EXISTS (SELECT NULL 
       FROM myothertable b 
       WHERE a.name LIKE CONCAT('%', b.name, '%')) 

Korzystanie Full Text Search MATCH (wymaga myothertable jest MyISAM)

SELECT a.* 
    FROM mytable a 
    JOIN myothertable b ON MATCH(a.name) AGAINST (b.name) 
+1

+1, aby uzyskać pełniejszą odpowiedź niż moja. Idź kucyki! – bernie

+0

@bernie: Podaję opcje, ale EXISTS to prawdopodobnie najlepszy wybór - byłeś pierwszy, +1 –

+0

Doskonała odpowiedź. Po prostu mała uwaga: 'MATCH' prawdopodobnie może dać oczekiwany wynik, który nie byłby oczekiwany – zerkms

0

Najlepszy sposób byłoby utworzyć funkcję o nazwie NameMatch()

Zapytanie końcowa:

SELECT * FROM mytable WHERE dbo.NameMatch(name) = 1 

Funkcja wyglądałby następująco:

create function dbo.NameMatch 
(@_name varchar(100)) 
returns bit 
as begin 

    declare @res bit 
    if exists (select 1 from myothertable where @_name like '%' + name + '%') 
    set @res = 1 
    else set @res = 0 
    return @res 

end 
+0

Nie - to faktycznie wykonałoby Row By Agonizing Row (RBAR). SQL jest oparty na SET ... –

+0

Możesz spróbować uruchomić powyżej na MSSQL 2000/2005/2008. To działa dobrze. Po prostu zrobiłem to samo. – Dhananjay

+0

"Praca" oznacza "działa jak najskuteczniej, jak tylko może". I pytanie jest MySQL, a nie SQL Server ... –

-1

pracował dla mnie

SELECT * 
FROM mytable 
WHERE name 
LIKE CONCAT('%',(SELECT name FROM myothertable),'%') 
+0

W MySQL 5.6 to zapytanie wyrzuca kod błędu: 1242. Podkwerenda zwraca więcej niż 1 wiersz. W jakiej wersji to uruchomiłeś? – Kingz

+0

Drogi Upewnij się, że podzapytanie zwróci tylko jeden rekord. w przeciwnym razie nie zadziała –

0

select * from t1 GDZIE t1.name IN (SELECT t2.name FROM t2) I (t1.title IN (SELECT t2.title FROM t2) LUB t1.surname IN (SELECT t2.surname FROM t2))

0

tylko inny sposób:

select a.field, b.code 
from table1 a 
inner join (select code from table2 where ....) b on a.field like CONCAT('%', b.code, '%') 
-1

ten ciąg działa dobrze dla mnie.

"WYBIERZ * Z tabeli 1 GDZIE pole jak CONCAT ('%', (SELECT id from table2), '%')";

+0

Nie działa, jeśli wewnętrzna opcja zwraca więcej niż jeden wiersz –

Powiązane problemy