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

Re:MySQL - podmíněný SELECT přes dvě tabulky
« Odpověď #45 kdy: 06. 10. 2019, 17:15:28 »
Nechť si Racchek vybere podle požadavku, ale ať tam proboha necpe INNER JOIN, když tomu struktura neodpovídá. Myslím, že je důležité si utvořit správné návyky a určitou štábní kulturu.
Ano, je důležité si utvořit správné návyky a určitou štábní kulturu. Takže pokud Racchek má požadavek vybrat z tbl1 ty záznamy, které jsou v tbl2 a mají tam allowed > 0 má krystalicky čistý učebnicový příklad na INNER JOIN, tak by ho tak také měl napsat. Tomu vašemu příkladu s INNER JOINem psaným pomocí OUTER JOINu, který je navíc špatně, ať se zdaleka vyhne. (Ten váš příklad by vyžadoval splnění jednoho předpokladu, který ale v zadání uveden není.)

Vážně by mne zajímalo, jakou ještě lepší strukturu, než tuhle, byste si pro INNER JOIN představoval.

Ano, přesně takto jsem to myslel. Vezmi sadu z tbl1.id_data, přičemž v tbl2.id_data musí existovat a zároveň tbl2.allowed>0


Re:MySQL - podmíněný SELECT přes dvě tabulky
« Odpověď #46 kdy: 06. 10. 2019, 19:54:14 »
Ano, přesně takto jsem to myslel. Vezmi sadu z tbl1.id_data, přičemž v tbl2.id_data musí existovat a zároveň tbl2.allowed>0

Pak je bude fungovat INNER JOIN, ale LEFT JOIN bude správnější, protože umožní obrátit výběr (selektovat záznamy, které mají allowed=0 nebo nemají odpovídající záznam v tbl2).

Re:MySQL - podmíněný SELECT přes dvě tabulky
« Odpověď #47 kdy: 06. 10. 2019, 20:00:38 »
Mít strukturu databáze, kde hodnoty >= 1 znamenají „povoleno“ a hodnoty 0 a NULL znamenají zakázáno, není dobrý nápad. Každý stav by měl být reprezentován právě jednou hodnotou.

NULL může reprezentovat implicitní nastavení (právo nebylo explicitně definované ani jako allow, ani jako disallow).
Správější by bylo tedy nikoliv "zakázáno", ale "nepovoleno".

NULL je v takovýchto případech naprosto správná hodnota, od toho je.

Můžu pak pokládat dotazy:
1. Kdo má povoleno? (allow = 1)
2. Kdo nemá povoleno? (variatněn: allow = 0 OR tbl2.id_data IS NULL nebo jen tbl2.id_data IS NULL)
3. Kdo má zakázáno? (allow = 0)

Všechny tyto tři dotazy můžete položit pouze v případě LEFT OUTER JOINU. S INNER JOINEM zvládnete obsloužit pouze otázky 1. a 3.

Re:MySQL - podmíněný SELECT přes dvě tabulky
« Odpověď #48 kdy: 06. 10. 2019, 20:37:28 »
Pak je bude fungovat INNER JOIN, ale LEFT JOIN bude správnější, protože umožní obrátit výběr (selektovat záznamy, které mají allowed=0 nebo nemají odpovídající záznam v tbl2).
Já bych se spíš soustředil na to, aby ten dotaz vracel ty záznamy, které má. Vzhledem k tomu, jak dlouho vám trvalo, než jste zjistil, kde máte chybu, bych nedoporučoval obcházet sémantický INNER JOIN zapsaný v SQL pomocí OUTER JOINu a přidané podmínky jenom proto, že pak dotaz snáze zmodifikujete do jiného arbitrárně vybraného dotazu.

Vzhledem k tomu, že nevíte vůbec nic o řešení doméně, totiž „obrácený výběr“ klidně může znamenat záznamy, které existují a mají allowed=0.

S INNER JOINEM zvládnete obsloužit pouze otázky 1. a 3.
S INNER JOINem samozřejmě zvládnu obsloužit i otázku 2. Už zase si pletete NULL hodnotu v datovém sloupci a neexistující záznam. To máte z toho vašeho čarování s JOINy – kdybyste se smířil s tím, že JOIN slouží ke spojení tabulek a varianta INNER nebo OUTER rozhoduje o tom, jak se bude zacházet se záznamy, které v některé tabulce neexistují, tyhle chyby byste nedělal. Neexistující záznam je něco jiného, než neexistující hodnota v záznamu, před čímž vy neustále svým OUTER JOINem zavíráte oči.

Re:MySQL - podmíněný SELECT přes dvě tabulky
« Odpověď #49 kdy: 06. 10. 2019, 20:39:48 »
S INNER JOINem samozřejmě zvládnu obsloužit i otázku 2. Už zase si pletete NULL hodnotu v datovém sloupci a neexistující záznam. To máte z toho vašeho čarování s JOINy – kdybyste se smířil s tím, že JOIN slouží ke spojení tabulek a varianta INNER nebo OUTER rozhoduje o tom, jak se bude zacházet se záznamy, které v některé tabulce neexistují, tyhle chyby byste nedělal. Neexistující záznam je něco jiného, než neexistující hodnota v záznamu, před čímž vy neustále svým OUTER JOINem zavíráte oči.

Nehovořím o datovém sloupci, ale o klíči, přes který se to spojuje. Id_data v joinované tabulce nikdy nebude NULL, kromě případu, že k joinu nedojde.


Logik

  • *****
  • 1 034
    • Zobrazit profil
    • E-mail
Re:MySQL - podmíněný SELECT přes dvě tabulky
« Odpověď #50 kdy: 06. 10. 2019, 23:12:43 »
Miroslav:
Citace
NULL může reprezentovat implicitní nastavení.... NULL je v takovýchto případech naprosto správná hodnota, od toho je.
To bych se hádal. Null znamená "nevím", "není jisté", "není definované". Proto se také chová tak jak se chová. "Nemá explicitně definované právo" není "nevím", to je přesně definovaný stav.
Použití NULL je IMHO v takovém případě nevhodné - např. proto, že to zesložiťuje dotazy (dotaz na explicitně nedefinovaná práva vypadá jinak než dotaz na zakázaná). V takovémto případě je IMHO nejlepší využít (not null) ENUM typu s hodnotami(ANO, NE, NEDEFINOVÁNO).
Ono vůbec, jak jsem psal, NULL je poměrně problematický rys SQL jazyka a je lepší se mu co to jde vyhýbat.

Filip:
Citace
....Vzhledem k tomu, jak dlouho vám trvalo, než jste zjistil....
Neschopnost myšlenku opustit.
Citace
S INNER JOINem samozřejmě zvládnu obsloužit i otázku 2.
A jak? Teda pokud nepoužijete nějaké except, což je jen zakuklený outer join.

Re:MySQL - podmíněný SELECT přes dvě tabulky
« Odpověď #51 kdy: 06. 10. 2019, 23:18:34 »
V takovémto případě je IMHO nejlepší využít (not null) ENUM typu s hodnotami(ANO, NE, NEDEFINOVÁNO).
Ono vůbec, jak jsem psal, NULL je poměrně problematický rys SQL jazyka a je lepší se mu co to jde vyhýbat.

V praxi je problematické právě to NEDEFINOVÁNO. Znamenalo by to ke každému nedefinovanému oprávnění ukládat záznam. Např. když založíte nového uživatele, musel byste ke všem uzlům v systému přidat záznam NEDEFINOVÁNO. Proti tomu NULL vznikne na pravé straně LEFT JOINU, pokud nenajde odpovídající záznam. Proto je potřeba s ním počítat. (OUTER JOINY by ostatně nemohly ani existovat, pokud by neměly nematchující sloupce doplnit NULLY).

Osobně proti NULLŮM nic nemám. Tam, kde může být definováno NOT NULL, je to jednodušší. Ne všude to jde. Pak to chce trochu cviku na jejich výskyt nezapomenout, a už to člověku ani nepřijde jako složitost.

Re:MySQL - podmíněný SELECT přes dvě tabulky
« Odpověď #52 kdy: 06. 10. 2019, 23:30:25 »
Nehovořím o datovém sloupci, ale o klíči, přes který se to spojuje. Id_data v joinované tabulce nikdy nebude NULL
Hezky jste si vyvrátil svůj předchozí komentář. vy v tom tedy máte děsný hokej… Datový sloupec allow může ve vašem příkladu nabývat hodnot 0, 1 a NULL. id_data nikdy NULL nebude. Spojuje se přes id_data, takže přes to připojíte řádek z druhé tabulky, a v něm může být allow=NULL, což je třeba ten váš případ implicitního nastavení. Samozřejmě může nastat i případ, že se žádný řádek nepřipojí, protože v druhé tabulce neexistuje – to je ale jiný případ, než vámi popisovaný případ allow=NULL.


kromě případu, že k joinu nedojde.
Ne, pořád si to pletete. Neexistence řádku a NULL hodnota v některém datovém sloupci jsou dvě různé věci. Dokonce i kdybyste měl řádek plný samých NULL hodnot (i to jde vyrobit), pořád je to něco jiného, než neexistující řádek. Nenechte se mást tím, že při OUTER JOINu doplní databáze NULL hodnoty na místo těch dat, pro která nemá řádky z druhé tabulky.

Re:MySQL - podmíněný SELECT přes dvě tabulky
« Odpověď #53 kdy: 06. 10. 2019, 23:37:28 »
Citace
S INNER JOINem samozřejmě zvládnu obsloužit i otázku 2.
A jak? Teda pokud nepoužijete nějaké except, což je jen zakuklený outer join.

Jak získám záznamy, které mají v tbl2 záznam s hodnotou allow = 0 nebo allow IS NULL? No jednoduše:

Kód: [Vybrat]
SELECT * FROM tbl1 JOIN tbl2 USING (id_data) WHERE allow = 0 OR allow IS NULL
Zaznamenal jste, že Miroslav Šilhavý určil pro implicitní nastavení hodnotu NULL, že? Aby mohl mít záznam hodnotu allow=NULL, musí existovat. Tudíž není ho INNER JOIN připojí.

Kdyby implicitní hodnota byla reprezentovaná neexistencí záznamu, to by bylo něco jiného.

Re:MySQL - podmíněný SELECT přes dvě tabulky
« Odpověď #54 kdy: 06. 10. 2019, 23:42:09 »
Zaznamenal jste, že Miroslav Šilhavý určil pro implicitní nastavení hodnotu NULL, že? Aby mohl mít záznam hodnotu allow=NULL, musí existovat. Tudíž není ho INNER JOIN připojí.

Kdyby implicitní hodnota byla reprezentovaná neexistencí záznamu, to by bylo něco jiného.

To jste mě špatně pochopil. Myšlena byla právě neexistence záznamu, která je ve výsledku joinu interpretována jako NULL. Vkládat řádek s hodnotou allow=NULL je pitomost, celý sloupec allow by bylo vhodné spíš deklarovat jako NOT NULL.

Re:MySQL - podmíněný SELECT přes dvě tabulky
« Odpověď #55 kdy: 06. 10. 2019, 23:46:41 »
To jste mě špatně pochopil. Myšlena byla právě neexistence záznamu
Nepochopil jsem vás špatně. Vy jste to špatně napsal. Neexistence záznamu je něco úplně jiného, než záznam, který má v jednom sloupci hodnotu NULL.

Re:MySQL - podmíněný SELECT přes dvě tabulky
« Odpověď #56 kdy: 06. 10. 2019, 23:49:48 »
Nepochopil jsem vás špatně. Vy jste to špatně napsal. Neexistence záznamu je něco úplně jiného, než záznam, který má v jednom sloupci hodnotu NULL.

Celou tuto diskusi vedeme o podmínce, která se aplikuje na výsledek INNER / OUTER JOINU.
Celá tato diskuse je od začátku o tom, že v tbl2 nemusí existovat odpovídající záznam.
Celá tato diskuse je následně o tom, jestli se dá neexistence záznamu (reprezentovaná NULLEM ve výsledku joinu) interpretovat jako zákaz.

Domníval jsem se, že jsme oba ve stejné diskusi a že není nutné opakovat v každém postu celý kontext.
Uznávám, moje chyba.
« Poslední změna: 06. 10. 2019, 23:51:52 od Miroslav Šilhavý »

Re:MySQL - podmíněný SELECT přes dvě tabulky
« Odpověď #57 kdy: 06. 10. 2019, 23:58:33 »
Domníval jsem se, že jsme oba ve stejné diskusi a že není nutné opakovat v každém postu celý kontext.
Není nutné opakovat celý kontext. Jenom je nutné neplést si dvě různé věci, „neexistenci záznamu“ a „záznam, který má v jednom sloupci hodnotu NULL“. Z této diskuse je vidět, že až to začnete rozlišovat, ozřejmí se vám mnoho věcí.

Re:MySQL - podmíněný SELECT přes dvě tabulky
« Odpověď #58 kdy: 07. 10. 2019, 00:03:48 »
Není nutné opakovat celý kontext. Jenom je nutné neplést si dvě různé věci, „neexistenci záznamu“ a „záznam, který má v jednom sloupci hodnotu NULL“. Z této diskuse je vidět, že až to začnete rozlišovat, ozřejmí se vám mnoho věcí.

O záznamu s hodnotou NULL jsem nikdy nemluvil, to jste si musel domyslet jako projekci Vašich myšlenek. Já řeším pouze otázku INNER / OUTER JOINU v kontextu toho, že v tbl2 může a nemusí příslušný záznam existovat. Pokud jsem hovořil o sloupci allow, jedině jakožto výsledném sloupci (outer) joinu.

Ukládat NULL do sloupce allow v tabulce tbl2 by byla hovadina. Pokud jste tímto směrem vedl argumentaci, pak zbytečně a můžeme toto téma opustit a znovu se věnovat pouze té otázce joinu a jeho interpretaci různých situací.

Re:MySQL - podmíněný SELECT přes dvě tabulky
« Odpověď #59 kdy: 07. 10. 2019, 00:16:08 »
O záznamu s hodnotou NULL jsem nikdy nemluvil, to jste si musel domyslet jako projekci Vašich myšlenek.
V tom případě to byl někdo jiný téhož jména.

NULL může reprezentovat implicitní nastavení

NULL je v takovýchto případech naprosto správná hodnota, od toho je.