Portál AbcLinuxu, 14. května 2025 05:50

Dotaz: MySQL – výběr na základě dat v jiné tabulce

30.6.2013 11:17 Tref
MySQL – výběr na základě dat v jiné tabulce
Přečteno: 1285×
Odpovědět | Admin
Dobrý den, mohl by mi, prosím, někdo poradit s tímto? Řekněme, že mám dvě tabulky:
table1                   table2
---------------          -----------------
id      int              id           int
/*     sth   */          table1_id    int
                         str2         text
Data potřebuji pouze z table1, ovšem jen ze řádků, jejichž id odpovídá table1_id. Podmínkou je LIKE %% v str2, nejsnáze asi vysvětleno příkladem:
table1
---------------
1     /* sth */
2     /* sth */

table2
---------------
1     1     cat
2     1     dog
3     1     horse
4     2     cat
5     2     dog
6     2     elephant
Pokud dotazu předám ca, vrátí se 1 a 2.
Pokud dotazu předám ca a g, vrátí se taktéž 1 a 2.
Pokud dotazu předám ca a or, vrátí se 1.
Pokud dotazu předám ca a abcd, nevrátí se nic. Vstupů v jednom dotazu může být neomezeně a výkon je důležitý (table1 obsahuje přes 160 tisíc řádků, table2 přes 280 tisíc).

Předem děkuji.


Řešení dotazu:


Nástroje: Začni sledovat (0) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

wamba avatar 30.6.2013 13:22 wamba | skóre: 38 | blog: wamba
Rozbalit Rozbalit vše Re: MySQL – výběr na základě dat v jiné tabulce
Odpovědět | | Sbalit | Link | Blokovat | Admin
no napadá mě použít GROUP_CONCAT
This would have been so hard to fix when you don't know that there is in fact an easy fix.
30.6.2013 13:41 Kit
Rozbalit Rozbalit vše Re: MySQL – výběr na základě dat v jiné tabulce
Odpovědět | | Sbalit | Link | Blokovat | Admin
SELECT * FROM table1 WHERE
    id IN (SELECT table1_id FROM table2 WHERE str2 LIKE '%orse%') AND
    id IN (SELECT table1_id FROM table2 WHERE str2 LIKE '%at%');
Pokud záleží na výkonu, není vhodné EAV používat.
30.6.2013 15:33 Tref
Rozbalit Rozbalit vše Re: MySQL – výběr na základě dat v jiné tabulce
Děkuji za funkční řešení.
15.7.2013 09:13 hyperventil
Rozbalit Rozbalit vše Re: MySQL – výběr na základě dat v jiné tabulce
1. misto (select ... and select ...) pouzij (like ... or like ...)

2. v pripade vetsich tabulek timto spolehlive zabijes mysql server. spravne reseni je pouzit join misto subselectu ve where casti.
rADOn avatar 2.7.2013 17:48 rADOn | skóre: 44 | blog: bloK | Praha
Rozbalit Rozbalit vše Re: MySQL – výběr na základě dat v jiné tabulce
Odpovědět | | Sbalit | Link | Blokovat | Admin
SELECT DISTINCT t1.* FROM table1 t1
JOIN table2 t2 ON t2.table1_id = t1.id
WHERE 1=1
AND t2.str LIKE '%whatever%'
AND t2.str LIKE '%whateverelse%'
Na vykon sere pes… pokud tam mas LIKE %% tak to stejne skonci fullscanem. Jestli se snazis zbastlit si made-by-samodoma fulltext, tak se snazis marne :-)

"2^24 comments ought to be enough for anyone" -- CmdrTaco
2.7.2013 22:44 axel
Rozbalit Rozbalit vše Re: MySQL – výběr na základě dat v jiné tabulce
Toto urcite nefunguje.
15.7.2013 15:38 j
Rozbalit Rozbalit vše Re: MySQL – výběr na základě dat v jiné tabulce
Toto zcela na 100% funguje a narozdil od tech hruz vejs je to jediny spravny reseni. Jen bych tam pridal left join, pokud je vazba 1:n (pripadne n:n) a ne 1:1.

Jenom nevim, nac tam davat 1=1 ... ;D.

A jak bylo receno, libovolnej like ... zabije vykon zcela spolehlive.
15.7.2013 16:01 Kit
Rozbalit Rozbalit vše Re: MySQL – výběr na základě dat v jiné tabulce
Možná to na 100 % funguje, ale zároveň je to 100% špatně, protože to nesplňuje zadání. Přečti si ho ještě jednou a pozorněji.
rADOn avatar 15.7.2013 19:00 rADOn | skóre: 44 | blog: bloK | Praha
Rozbalit Rozbalit vše Re: MySQL – výběr na základě dat v jiné tabulce
1=1 je vzdy true a query optimizer to vyhodi. je to dobry jen k tomu ze kdyz chci zakomentovat prvni podminku za tim tak nemusim odmazavat prebytecne ANDitko a pak zase naopak. ditto kdyz skladas strojove dotaz pro nejaky filtr.
"2^24 comments ought to be enough for anyone" -- CmdrTaco
Josef Kufner avatar 16.7.2013 09:16 Josef Kufner | skóre: 70
Rozbalit Rozbalit vše Re: MySQL – výběr na základě dat v jiné tabulce
Na tohle je lepší používat něco jako je FluentPDO. Tedy přiměřeně chytré lepítko fragmentů do výsledného selectu, které ví, v jakém pořadí je má slepit, takže lze pohodlně přidávat podmínky dle aktuálních potřeb (např. různá dynamická filtrování).
Hello world ! Segmentation fault (core dumped)
16.7.2013 10:46 Lyco
Rozbalit Rozbalit vše Řešení s JOINem
Odpovědět | | Sbalit | Link | Blokovat | Admin
Jde to i tím JOINem, ale musí se na to jinak:
SELECT id FROM table1 JOIN t2 ON table1.id = table2.t1_id WHERE 
  str2 LIKE '%ca%' 
  OR str2 LIKE '%or%' 
GROUP BY t1.id HAVING count(str2) = $count;
kde $count je počet podmínek (v tomhle případě 2).

Každopádně souhlasím s předřečníky, že jakmile se používá LIKE '%něco%' tak nemá smysl výkon řešit - tohle bude pomalé pro jakýkoli netriviální počet záznamů, protože se nedá použít index. (Tedy alespoň v MySQL - PostgreSQL umí použít trigramový index, pokud to něco má aspoň 3 znaky. Tam to bude celkem rychlé, ale ten index bude celkem ohromný.)
Tarmaq avatar 16.7.2013 11:46 Tarmaq | skóre: 39
Rozbalit Rozbalit vše Re: Řešení s JOINem
S tim uvedenym joinem to nefunguje spravne. Nepocita totiz s variantou, ze pro jeden zaznam z table1 matchne vice zaznamu v table2. Pro data uvedena v zadani uvadim priklad:
SELECT t1.id FROM table1 t1
JOIN table2 t2 ON t1.id = t2.table1_id WHERE
  t2.str2 LIKE '%t%'
GROUP BY t1.id HAVING count(t2.str2) = 1;
Vrati jen 1, pritom by melo vratit i 2.
Don't panic!

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.