MySQL - podmíněný SELECT přes dvě tabulky

Re:MySQL - podmíněný SELECT přes dvě tabulky
« Odpověď #90 kdy: 13. 10. 2019, 12:07:57 »
Citace od: Miroslav Šilhavý kdy 13. 10. 2019, 11:04:29
Pře je pouze o tom, jestli je dobré přemýšlet trochu dopředu a tvořit s k takovému přemýšlení návyk.
Nikoli, tohle je pouze vaše demagogie. Na tom, že je potřeba přemýšlet trochu dopředu, se shodneme. Neshodneme se na tom, co máme ve předu očekávat.

Citace od: Miroslav Šilhavý kdy 13. 10. 2019, 11:04:29
Chápu kam míříte, ale zkoušíte to trochu demagogicky. Hlavní entitou dotazu je tbl1, z ní se čerpají informace. V tbl2 je pouze přívěsek, který existovat může a nemusí. Takže nemůžete z tbl2 najednou udělat hlavní entitu.
Že je tbl1 hlavní entitou dotazu se z uvedené databázové struktury pozná jak? Když budu mít tabulku entit a vedle ní číselník, v té tabulce entit záznamy mohou existovat a nemusí, zatímco číselník bude vždy úplný.


e3k

  • ****
  • 270
Re:MySQL - podmíněný SELECT přes dvě tabulky
« Odpověď #91 kdy: 13. 10. 2019, 20:04:20 »
Citace od: Miroslav Šilhavý kdy 13. 10. 2019, 10:31:00
Citace od: e3k kdy 12. 10. 2019, 21:11:38.
Kazdopadne pri druhom zadani prikladu by uz INNER JOIN uplne stacil.

On už by při prvním zadání stačil INNER JOIN, o tom není vůbec pochyb. Jen je to špatně navržené.
tak to fakt neviem jak by som to spravil INNER JOINOM ked v 2hej tabulke nie su vsetky ID prvej. pokial sa to da tak to musi byt riadny brain fuck.

Re:MySQL - podmíněný SELECT přes dvě tabulky
« Odpověď #92 kdy: 13. 10. 2019, 20:06:26 »
Citace od: e3k kdy 13. 10. 2019, 20:04:20
tak to fakt neviem jak by som to spravil INNER JOINOM ked v 2hej tabulke nie su vsetky ID prvej. pokial sa to da tak to musi byt riadny brain fuck.

Požadavek byl na to vyhledat záznamy v tbl1, které mají v tbl2 odpovídající záznam a tbl2.allowed > 0.
Tedy INNER JOIN i OUTER JOIN navrátí v tomto případě stejný výsledek.

Re:MySQL - podmíněný SELECT přes dvě tabulky
« Odpověď #93 kdy: 14. 10. 2019, 07:45:42 »
Citace od: Miroslav Šilhavý kdy 13. 10. 2019, 20:06:26
Požadavek byl na to vyhledat záznamy v tbl1, které mají v tbl2 odpovídající záznam a tbl2.allowed > 0.
Požadavek byl jiný, přečtěte si to v prvním příspěvku.

Citace od: Miroslav Šilhavý kdy 13. 10. 2019, 20:06:26
Tedy INNER JOIN i OUTER JOIN navrátí v tomto případě stejný výsledek.
Takhle napsané to vypadá, že oba JOINy se stejnou podmínkou vrátí stejný výsledek. Jenže to není pravda, u OUTER JOINu musíte do filtrovacích podmínek přidat i tu podmínku, která z něj udělá INNER JOIN. Obecně samozřejmě každý INNER JOIN jde napsat pomocí OUTER JOINu tím, že přidáte další podmínky. Obšem jak bylo vidět v této diskusi, není to vždy snadné...

Re:MySQL - podmíněný SELECT přes dvě tabulky
« Odpověď #94 kdy: 14. 10. 2019, 08:58:16 »
Citace od: Filip Jirsák kdy 14. 10. 2019, 07:45:42
Takhle napsané to vypadá, že oba JOINy se stejnou podmínkou vrátí stejný výsledek. Jenže to není pravda, u OUTER JOINu musíte do filtrovacích podmínek přidat i tu podmínku, která z něj udělá INNER JOIN. Obecně samozřejmě každý INNER JOIN jde napsat pomocí OUTER JOINu tím, že přidáte další podmínky. Obšem jak bylo vidět v této diskusi, není to vždy snadné...

Aha, tak zde je ta chyba, kterou děláte. V tomto případě žádnou podmínku navíc nepotřebujete. Stačí bohatě
SELECT * FROM tbl1 LEFT OUTER JOIN tbl2 USING (id_data) WHERE tbl2.allowed > 0.

Pokud nedojde k joinu, pak nebude ani splněná podmínka tbl2.allowed > 0.


Re:MySQL - podmíněný SELECT přes dvě tabulky
« Odpověď #95 kdy: 14. 10. 2019, 09:27:49 »
Citace od: Miroslav Šilhavý kdy 14. 10. 2019, 08:58:16
Aha, tak zde je ta chyba, kterou děláte. V tomto případě žádnou podmínku navíc nepotřebujete. Stačí bohatě
SELECT * FROM tbl1 LEFT OUTER JOIN tbl2 USING (id_data) WHERE tbl2.allowed > 0.

Pokud nedojde k joinu, pak nebude ani splněná podmínka tbl2.allowed > 0.
Aha, takže to vaše ,,dotaz má být co nejvíce univerzální" znamená, že tam ty podmínky pokaždé budete psát úplně od začátku. Čím dál lepší.

Re:MySQL - podmíněný SELECT přes dvě tabulky
« Odpověď #96 kdy: 14. 10. 2019, 09:29:11 »
Citace od: Filip Jirsák kdy 14. 10. 2019, 09:27:49
Aha, takže to vaše ,,dotaz má být co nejvíce univerzální" znamená, že tam ty podmínky pokaždé budete psát úplně od začátku. Čím dál lepší.

Co prosím? Já tvrdím, že správně napsaný skelet dotazu je takový, kde se podmínka "metá" jen do WHERE a nemusí se nic dalšího měnit. Takový skelet lze zobecnit do VIEW a pak pracovat jen nad ním.

Re:MySQL - podmíněný SELECT přes dvě tabulky
« Odpověď #97 kdy: 14. 10. 2019, 10:09:28 »
Citace od: Miroslav Šilhavý kdy 14. 10. 2019, 09:29:11
Co prosím? Já tvrdím, že správně napsaný skelet dotazu je takový, kde se podmínka "metá" jen do WHERE a nemusí se nic dalšího měnit. Takový skelet lze zobecnit do VIEW a pak pracovat jen nad ním.

A pak někdo do toho WHERE dá takovouhle podmínku:
SELECT * FROM tbl1 LEFT OUTER JOIN tbl2 USING (id_data) WHERE tbl2.allowed IS NULL

Případně to udělá nad tím view – ideálně, když k tabulce ani nebude mít přístup. To už pak tu vaši chybu s použitím chybného JOINu ani v SELECTu neopraví. I když ve výsledku by to asi bylo dobře – konečně by opravil ten váš JOIN v pohledu na správný INNER JOIN.

Re:MySQL - podmíněný SELECT přes dvě tabulky
« Odpověď #98 kdy: 14. 10. 2019, 10:12:32 »
Citace od: Filip Jirsák kdy 14. 10. 2019, 10:09:28
A pak někdo do toho WHERE dá takovouhle podmínku:
SELECT * FROM tbl1 LEFT OUTER JOIN tbl2 USING (id_data) WHERE tbl2.allowed IS NULL

Ano, ale přesně o to jde, aby mohl udělat. Tedy vyselektovat si záznamy, ke kterým není právo "allowed" explicitně dané.

Jako další příklad toho, co může dávat smysl je dotaz:
SELECT  * FROM tbl1 LEFT OUTER JOIN tbl2 USING (id_data) WHERE tbl2.id_data IS NULL OR tbl2.allowed = 0

Re:MySQL - podmíněný SELECT přes dvě tabulky
« Odpověď #99 kdy: 14. 10. 2019, 16:37:48 »
Citace od: Miroslav Šilhavý kdy 14. 10. 2019, 10:12:32
Ano, ale přesně o to jde, aby mohl udělat. Tedy vyselektovat si záznamy, ke kterým není právo "allowed" explicitně dané.
Mně na tom teda poněkud vadí, že je ten dotaz špatně. Chtěl jsem záznamy, které v tbl2 existují a mají tam allowed IS NULL, ale vrátilo mi to i záznamy, které v tbl2 vůbec neexistují.

Citace od: Miroslav Šilhavý kdy 14. 10. 2019, 10:12:32
Jako další příklad toho, co může dávat smysl je dotaz:
SELECT  * FROM tbl1 LEFT OUTER JOIN tbl2 USING (id_data) WHERE tbl2.id_data IS NULL OR tbl2.allowed = 0
Pokud často píšete dotazy, ve kterých neexistence záznamu nebo NULL hodnota má stejný význam, jako nějaká jiná hodnota, tedy vyskytují se vám tam konstrukce ... IS NULL OR ... , je to známka toho, že máte špatně navrženou strukturu databáze. NULL není jedna z mnoha hodnot, NULL je speciální hodnota, výjimečná – proto se s ní nepracuje pomocí běžných operátorů = nebo !=, ale má speciální operátory; proto je ,,nakažlivá" a když se objeví u běžných operátorů, je na výstupu zase NULL...

Re:MySQL - podmíněný SELECT přes dvě tabulky
« Odpověď #100 kdy: 14. 10. 2019, 16:41:26 »
Citace od: Filip Jirsák kdy 14. 10. 2019, 16:37:48
Mně na tom teda poněkud vadí, že je ten dotaz špatně. Chtěl jsem záznamy, které v tbl2 existují a mají tam allowed IS NULL, ale vrátilo mi to i záznamy, které v tbl2 vůbec neexistují.

Pokud dáte podmínku WHERE allowed > 0, pak Vám to tyto záznamy přirozeně nevrátí.

Citace od: Filip Jirsák kdy 14. 10. 2019, 16:37:48
Pokud často píšete dotazy, ve kterých neexistence záznamu nebo NULL hodnota má stejný význam, jako nějaká jiná hodnota, tedy vyskytují se vám tam konstrukce ... IS NULL OR ... , je to známka toho, že máte špatně navrženou strukturu databáze. NULL není jedna z mnoha hodnot, NULL je speciální hodnota, výjimečná – proto se s ní nepracuje pomocí běžných operátorů = nebo !=, ale má speciální operátory; proto je ,,nakažlivá" a když se objeví u běžných operátorů, je na výstupu zase NULL...

Jedná se o (primární / vzdálený) klíč. Ten může mít buďto hodnotu a dojde k joinu, nebo nedojde k joinu a pak záznam neexistuje. NULL v klíči má jasně daný význam. U ostatních sloupců, mimo klíčů platí to, co píšete.

Re:MySQL - podmíněný SELECT přes dvě tabulky
« Odpověď #101 kdy: 14. 10. 2019, 17:03:03 »
Citace od: Miroslav Šilhavý citoval ale pak zapomněl kdy 14. 10. 2019, 10:12:32
Citace od: Filip Jirsák kdy 14. 10. 2019, 10:09:28
A pak někdo do toho WHERE dá takovouhle podmínku:
SELECT * FROM tbl1 LEFT OUTER JOIN tbl2 USING (id_data) WHERE tbl2.allowed IS NULL

Citace od: Miroslav Šilhavý kdy 14. 10. 2019, 16:41:26
Pokud dáte podmínku WHERE allowed > 0, pak Vám to tyto záznamy přirozeně nevrátí.
Ta podmínka je o dva komentáře výš, sám jste ji ve svém předchozím komentáři citoval. Mám pro vás tip – když píšete komentář, na stránce níž jsou předchozí komentáře v diskusi. Abyste ze sebe neudělal hlupáka, bývalo by stačilo odrolovat o jednu obrazovku dolů.

Citace od: Filip Jirsák kdy 14. 10. 2019, 16:37:48
Jedná se o (primární / vzdálený) klíč. Ten může mít buďto hodnotu a dojde k joinu, nebo nedojde k joinu a pak záznam neexistuje. NULL v klíči má jasně daný význam. U ostatních sloupců, mimo klíčů platí to, co píšete.
Pro neexistenci záznamu platí to samé, co pro NULL. Není to stejná hodnota, jako kterákoli jiná, je speciální –ostatně i proto se při OUTER JOINu neexistující záznamy mapují právě na NULL, což je jiná speciální hodnota. Pokud chcete v SELECTu říct, že vás neexistující záznamy nezajímají, uděláte to právě pomocí INNER JOINu. Tím si zajistíte, že se ty neexistující záznamy ve výsledné sadě ani neobjeví, tím pádem není nutné je mapovat na NULL a tím pádem ani nemusíte NULL hodnotu řešit.

Re:MySQL - podmíněný SELECT přes dvě tabulky
« Odpověď #102 kdy: 14. 10. 2019, 17:09:26 »
Citace od: Filip Jirsák kdy 14. 10. 2019, 17:03:03
Pro neexistenci záznamu platí to samé, co pro NULL. Není to stejná hodnota, jako kterákoli jiná, je speciální –ostatně i proto se při OUTER JOINu neexistující záznamy mapují právě na NULL, což je jiná speciální hodnota. Pokud chcete v SELECTu říct, že vás neexistující záznamy nezajímají, uděláte to právě pomocí INNER JOINu. Tím si zajistíte, že se ty neexistující záznamy ve výsledné sadě ani neobjeví, tím pádem není nutné je mapovat na NULL a tím pádem ani nemusíte NULL hodnotu řešit.

:) jenže to jsme pořád u toho samého. Pokud si "SELECT * FROM tbl1 LEFT JOIN tbl2" vyčleníte do VIEW, můžete pak s tím samým VIEW pracovat všemi způsoby. Třeba tím, že do WHERE doplníte allowed > 0, nebo že tbl2.id_data IS NULL.

Je pochopitelně dost účelné mít jedno VIEW a pracovat s ním jen v podmínce.

e3k

  • ****
  • 270
Re:MySQL - podmíněný SELECT přes dvě tabulky
« Odpověď #103 kdy: 14. 10. 2019, 20:07:43 »
Citace od: Filip Jirsák kdy 14. 10. 2019, 16:37:48ale vrátilo mi to i záznamy, které v tbl2 vůbec neexistují.
ano o tom je left outer JOIN. vitajte v SQL realite :)
a ano nechcete mat NULL na vystupe preto to napisete tak aby tam nebol.

Re:MySQL - podmíněný SELECT přes dvě tabulky
« Odpověď #104 kdy: 14. 10. 2019, 20:09:52 »
Citace od: e3k kdy 14. 10. 2019, 20:07:43
Citace od: Filip Jirsák kdy 14. 10. 2019, 16:37:48ale vrátilo mi to i záznamy, které v tbl2 vůbec neexistují.
ano o tom je left outer JOIN. vitajte v SQL realite :)
a ano nechcete mat NULL na vystupe preto to napisete tak aby tam nebol.

To je samozřejmě blbost. Je-li podmínka allowed > 0, nemůže to navrátit sloupce, které obsahují NULL. Nenajoinované záznamy tam mají NULL, takže se neobjeví.