LEFT JOIN filtrování podle více parametrů
- sejmor
- Člen | 63
Zdravím … potřebuju naťuknout. Já prostě pořád tu nette databázi nemám pod kůží
Mám tabulku variant produktů se sloupcemi id,popis
varianta(id, popis)
a tabulka parametrů variant
varianta_parametr(id, varianta_id, parametr_id, hodnota_id)
parametr_id a hodnota_id jsou cizí klíče do tabulek, kde jsou parametry a jejich hodnoty definované – to ale není podstatné
Potřeboval bych udělat dotaz, který mi vybere všechny varianty, které mají v tabulce parametrů záznam parametr_id=5 a hodnota_id=35 a zároveň mají záznam parametr_id=11 a hodnota_id=122
Pokud bych chtěl filtrovat pouze podle prvního požadavku tak udělám
<?php
$selection=$connection->table('varianta')->where(':varianta_parametr.parametr_id=5 AND :varianta_parametr.hodnota_id=35')
?>
Ale jak to udělat aby mi fungovaly oba požadavky … přes další where už cesta nevede takže se musí asi přes HAVING, ale za boha na to nemůžu přijít.
Díky moc
- Mysteria
- Člen | 797
Takhle jednoduše to nefunguje?
->where(':varianta_parametr.parametr_id=5 AND :varianta_parametr.hodnota_id=35 AND :varianta_parametr.parametr_id=11 AND :varianta_parametr.hodnota_id=122')
Having určitě ne, protože to je na podmínky pro agregační funkce typu COUNT a podobně.
Editoval Mysteria (16. 9. 2016 8:44)
- CZechBoY
- Člen | 3608
Přidat bych
->group('varianta_id')
->having('COUNT(parameter_id)', 2);
group by varianta_id having count(parametr_id) = 2
@Mysteria to nedává smysl, jak můžeš mít v jednom řádku v jedný tabulce dvě hodnoty pro jeden sloupec? Když už tak by to chtělo přidat další join na tu stejnou tabulku variant.
Editoval CZechBoY (16. 9. 2016 8:59)
- sejmor
- Člen | 63
@Mysteria to by fungovalo v případě, že by parametry byly ve sloupcích. Oni jsou ale v řádcích a já v podstatě potřebuji zjistit jestli pro danou variantu jsou zmíněné dva řádky (dva parametry s konkrétní hodnotou)… což právě asi vyžaduje HAVING
@CZechBoY … nějak takhle to bude. Pokud tomu rozumím tak tvé řešení chápu jako že agreguji výsledky, které mají 2 řádky. Ale já tam potřebuji dostat i tu druhou podmínku a nevím kam.
- CZechBoY
- Člen | 3608
@sejmor ajo zapomněl jsem ti tam přidat OR
$parameterFilterWhere = ':varianta_parametr.parametr_id=? AND :varianta_parametr.hodnota_id=?';
$selection = $context->table('varianta')
->where("(({$parameterFilterWhere}) OR ({$parameterFilterWhere}))", 5, 35, 11, 122);
->group('varianta.varianta_id')
->having('COUNT(:varianta_parametr.parametr_id)', 2);
edit: odebráno pole parametrů pro where a použity variabilní parametry
Editoval CZechBoY (16. 9. 2016 11:50)
- sejmor
- Člen | 63
pokud se nepletu tak potřebuji tento dotaz
select * from varianta
LEFT JOIN varianta_parametr as p1 on p1.parametr_id=5 AND p1.hodnota_id=35 AND p1.varianta_id=varianta.id
LEFT JOIN varianta_parametr as p2 on p2.parametr_id=11 AND p2.hodnota_id=122 AND p2.varianta_id=varianta.id
WHERE p1.parametr_id=5 AND p1.hodnota_id=35 AND p2.parametr_id=11 AND p2.hodnota_id=122
- sejmor
- Člen | 63
@CZechBoY Vypadá to že to bude ono (parametry pro where v hranatých závorkách mi nejdou) … dal jsem následující dotaz:
$parameterFilterWhere = ':varianta_parametr.parametr_id=? AND :varianta_parametr.hodnota_id=?';
$this->varianty=$context->table('varianta')
->where("(({$parameterFilterWhere}) OR ({$parameterFilterWhere}))",5,35,11,122)
->group('varianta.id')
->having('COUNT(:varianta_parametr.parametr_id)=2')
->order('varianta.id');
A hází mi správný výsledky jako ten můj napsaný SQL dotaz… teď to jenom obalit a správně dynamicky sestavit ten where podle počtu vyplněných parametrů, ale to už bude doufám rutina
DÍKY MOC !
- sejmor
- Člen | 63
@CZechBoY … ještě jenom jeden dotaz – vrtá mi to hlavou. Jde o ten druhý způsob řešení v nette DB. Jak píšeš „další join na tu stejnou tabulku variant“ … v podstatě abych mi to vygenerovalo ten můj SQL dotaz bez GROUP a HAVING. Jak ho donutím aby udělal 2 x LEFT JOIN na stejnou tabulku ? Jde mi o pochopení :)
- norbe
- Backer | 405
Píšu z hlavy, ale mělo by jít zhruba takto:
$context->table('varianta')
->alias(':varianta_parametr', 'p1')
->alias(':varianta_parametr', 'p2')
// ->joinWhere('p1', 'p1.parametr_id', 5)
// ->joinWhere('p1', 'p1.hodnota_id', 35)
// ->joinWhere('p2', 'p2.parametr_id', 11)
// ->joinWhere('p2', 'p2.hodnota_id', 122)
->where('p1.parametr_id', 5)
->where('p1.hodnota_id', 35)
->where('p2.parametr_id', 11)
->where('p2.hodnota_id', 122);
JoinWhere jsem zakomentoval, jelikož dle mého není potřeba.
Edit: Předpokládá nette database v 2.4+
Editoval norbe (16. 9. 2016 14:16)