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 »
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.

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

  • ****
  • 262
    • Zobrazit profil
    • E-mail
Re:MySQL - podmíněný SELECT přes dvě tabulky
« Odpověď #91 kdy: 13. 10. 2019, 20:04:20 »
.
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 »
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 »
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.

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 »
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 »
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 »
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 »
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:
Kód: [Vybrat]
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 »
A pak někdo do toho WHERE dá takovouhle podmínku:
Kód: [Vybrat]
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 »
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í.

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 »
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í.

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 »
A pak někdo do toho WHERE dá takovouhle podmínku:
Kód: [Vybrat]
SELECT * FROM tbl1 LEFT OUTER JOIN tbl2 USING (id_data) WHERE tbl2.allowed IS NULL

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ů.

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 »
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

  • ****
  • 262
    • Zobrazit profil
    • E-mail
Re:MySQL - podmíněný SELECT přes dvě tabulky
« Odpověď #103 kdy: 14. 10. 2019, 20:07:43 »
ale 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 »
ale 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í.