reklama

Zobrazit příspěvky

Tato sekce Vám umožňuje zobrazit všechny příspěvky tohoto uživatele. Prosím uvědomte si, že můžete vidět příspěvky pouze z oblastí Vám přístupných.


Příspěvky - Miroslav Šilhavý

Stran: 1 [2] 3 4 ... 137
16
Vývoj / Re:MySQL - podmíněný SELECT přes dvě tabulky
« kdy: 16. 10. 2019, 13:19:38 »
Zadání vám klidně může připadat hloupé, pak je ale potřeba s tím zadáním polemizovat, ne si potichoučku řešit něco jiného. Takže za sebe bych to uzavřel, že než začnete řešit, jaký typ JOINu je nejlepší, je nejprve potřeba si pořádně přečíst zadání.

To je o tom, jestli chcete být programátorská lopata, která nechce rozumět reálnému prostředí a co jí není vyspecifikováno do puntíku, tak to ignoruje. Nebo jestli chcete program (včetně SQL) opravdu navrhovat. Pak musíte přemýšlet o krok dál.

Zadání bylo naprosto přesně zadané: struktura dat byla dána tím, že "v tbl2 může a nemusí existovat odpovídající záznam", zatímco podmínka dotazu byla dána "allowed > 0". Naopak vy jste ze zadání naprosto nadbytečně dovodil, že OUTER JOIN se dá redukovat na INNER JOIN.

17
Windows a jiné systémy / Re:Úprava Windows Exploreru
« kdy: 15. 10. 2019, 12:31:35 »
No já se přiznám, i když tím asi mnohé teď zklamu, já ten explorer chtěl trochu "přisprostit".

...áno, na to jsou programy... Zejména při psychiatrických nemocnicích. :)

18
Vývoj / Re:MySQL - podmíněný SELECT přes dvě tabulky
« kdy: 14. 10. 2019, 21:53:24 »
Pořád se slepě řídíte strukturou tabulek a neberete v úvahu význam dat. Pokud záznamy s neexistující vazbou nemají žádný význam, nemá smysl vytvářet nad nimi pohled, abyste je následně při každém použití toho pohledu musel odfiltrovat. Já jsem nepsal o pohledech, které přidávají jednu podmínku, ale o pohledech, které reprezentují různá data. Např. pokud je vedoucí zaměstnanec definován tím, že má podřízené, nemá smysl vytvářet si pohled s vedoucími, který bude obsahovat i ty, kteří žádné podřízené nemají, a ty z něj pak při každém použití odfiltrovávat.

Přesně naopak. V aplikaci můžu chtít zobrazit všechny vedoucí, co mají podřízené zaměstnance. Ale také můžu chtít (a je to dost běžné) na jiném místě zobrazit i ty, co (už) žádné podřízené nemají. Tedy jak existence, tak neexistence navázaného záznamu je významná. Struktura dat je pro oba záměry shodná, liší se jen v podmínce filtru.

19
Vývoj / Re:MySQL - podmíněný SELECT přes dvě tabulky
« kdy: 14. 10. 2019, 21:15:41 »
Pokud dávají smysl oba dva přístupy, udělám dva pohledy. Vy za každý vytvořený pohled platíte, nebo proč je pro vás tak důležité, že je ten pohled jeden a ne dva? Navíc se ty dva pohledy používají v různých situacích, takže se mi to krásně oddělí. Dost možná ty pohledy budou mít i jiné sloupce nebo dokonce připojené jiné další tabulky.

Pokud mám interpretovat určitou vazbu dat, je výhodné mít jeden pohled, třeba i se všemi sloupci, co se nabízejí. V následném selektu pak sloupce omezím jen na ty, které potřebuji. Tím, že v pohledu jsou k dispozici, nic neztratím, ani na výkonu.

Pokud potřebuji mít připojené další tabulky, není nic neobvyklého nad existující pohled postavit další, s dalším joinem.

A proč na to nechci mít dva oddělené pohledy? Inu protože pohledy mají zvyšovat přehlednost - čím méně jich je, tím snáz se revidují. Pokud mi dva pohledy opakují tu stejnou vazbu a jen přidávají podmínku, nedává to moc smysl. Ale kdybych to přeci jen chtěl mít, tak si nejprve udělám pohled interpretující strukturu dat, a teprve nad něj postavím speciální pohledy s filtry. V praxi se setkávám s pohledy s filtry jen v případě, kdy slouží k omezení přístupu k datům (uživatel nedostane práva na samotné tabulky, ale dostane práva jen na zafiltrovaný pohled).

Typicky, mám-li hlavičku dokladu a k ní navázaných 0-nekonečno položek dokladu, pak použiju OUTER JOIN a uložím to jako view. Nad ním pak mohu stavět agregáty (např. count položek). Ze stejného pohledu mi vypadnou jak doklady bez položek, tak doklady s položkami. Po agregaci u bezpoložkových dokladů získám count=0. Nebo použiju agregáty nad parcelami dat. Tento přístup je mnohem výhodnější, než abych v aplikačním kódu zvlášť selektoval doklady s položkami, zvlášť volal agregační funkce, a zvlášť selektoval doklady bez polože.

V případě stromu oprávnění potřebuji od zkoumaného uzlu směrem nahoru vyhodnocovat přístupové oprávnění. Pokud není určeno (OUTER JOIN navrátí v klíči NULL), je to indikátor k tomu přejít k dalšímu nadřazenému uzlu a vyhodnotit dědění práv. Pokud bych měl mít jedno view na existující práva a druhé na neexistující práva, musel bych joinovat tyto dvě views proti sobě. Pokud to mám v jednom provedu JOIN téhož view sama na sebe.

Prostě příkladů, kdy se to hodí je bezpočet a naopak málo případů je, kdy to může být škodlivé.

Na druhou stranu si uvědomuji, že spousta programátorů není schopna napsat select s více než třemi joiny, neumějí joinovat tabulku sama na sebe, zpracovávat parcely dat atd. atd. Právě proto si myslím, že je dobré radit jaké možnosti SQL nabízí a trpělivě vysvětlovat, že SQL optimalizace je vždy úspěšnější, než logiku programovat v aplikaci. Příklad Raccheka je přesně z toho ranku, kdy se dá poradit jednoduché řešení (INNER JOIN), ale i ukázat, že existuje i jiný, a možná zajímavý přístup k věci.

INNER JOIN bych používal zejména tam, kde se neočekává, že odpovídající záznam neexistuje - např. zmíněné číselníky, nebo pravá strana dynamické vazby (tbl1 LEFT JOIN tbl_vazba INNER JOIN tbl_hodnoty - první join nemusí nastat, ale pokud nastane, tak pravý už je obligatorní).

20
Vývoj / Re:MySQL - podmíněný SELECT přes dvě tabulky
« 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í.

21
Vývoj / Re:MySQL - podmíněný SELECT přes dvě tabulky
« 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.

22
Vývoj / Re:MySQL - podmíněný SELECT přes dvě tabulky
« 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.

23
Vývoj / Re:MySQL - podmíněný SELECT přes dvě tabulky
« 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

24
Vývoj / Re:MySQL - podmíněný SELECT přes dvě tabulky
« 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.

25
Vývoj / Re:MySQL - podmíněný SELECT přes dvě tabulky
« 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.

26
Vývoj / Re:MySQL - podmíněný SELECT přes dvě tabulky
« 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.

27
Vývoj / Re:MySQL - podmíněný SELECT přes dvě tabulky
« kdy: 13. 10. 2019, 11:04:29 »
Na tomhle dotazu se evidentně neshodneme. Jak by tedy podle vás vypadal správně navržený SELECT pro tohle zadání?

Ale my se v zásadě shodujeme, obě řešení dávají tentýž výsledek.
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.

Chci všechny záznamy z tbl2, které mají allowed > 0, a k nim připojit odpovídající záznam z tbl1. Pro každý záznam z tbl2 existuje záznam v tbl1.

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.

28
Vývoj / Re:MySQL - podmíněný SELECT přes dvě tabulky
« kdy: 13. 10. 2019, 10:31:00 »
.
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é.

29
Vývoj / Re:MySQL - podmíněný SELECT přes dvě tabulky
« kdy: 12. 10. 2019, 11:41:22 »
Opakuji ještě jednou – tady je struktura dat taková, že se zabýváme jenom záznamy existujícími v tbl2.

Asi to neumím napsat, abyste mě pochopil. Nemyslím strukturu dotazu, ale strukturu databáze. Ta byla popsána tak, že v tbl2 může a nemusí záznam existovat.

Neustále naznačujete, že INNER JOIN by se měl používat jenom tam, kde obě tabulky obsahují identickou sadu entit, akorát ke každé jedné entitě nesou jinou sadu vlastností. Že se INNER JOIN vůbec nemá implementačně lišit od OUTER JOINu, nýbrž že je to jenom komentář pro databázového specialistu, který mu říká „obě tabulky mají stejný počet záznamů, které si navzájem odpovídají“, resp. „vlastně by to měla být jen jedna tabulka, ale z nějakého důvodu je rozdělená na dvě“. V obou tabulkách by tedy mělo být nastavené FOREIGN KEY na tu druhou tabulku. Pokud by byl INNER JOIN přes více tabulek, muselo by to platit pro všechny a FOREIGN KEY by zřejmě měly mít každá s každou.

Jsou situace, kdy máte obecně definováno, že záznam musí existovat. Např. na dokladu uvedený odběratel (tabulka odběratelů však slouží více účelům), nebo vazba na číselníky (opět využívané z více míst). Tam je INNER JOIN na místě.

----

Pokud tedy tazatel napsal, že v tbl2 nemusí záznam být - pak je tato skutečnost nějak významná (něco vyjadřuje). Pokud tento stav zakryjete INNER JOINEM, můžete zaplakat nad výdělkem. Bohatě stačí, aby chtěl Racchek vybrat záznamy které mají allowed=0 NEBO nemají odpovídající záznam, a už je v háji a bude přepisovat nejen podmínku, ale i JOINY.

SQL je velmi chytře navržené, ne nadarmo jsou HAVING, WHERE a ORDER BY až na konci - v nich se máte rejpat. Co je nad nimi má být co nejvíc zobecněné.

30
Vývoj / Re:MySQL - podmíněný SELECT přes dvě tabulky
« kdy: 12. 10. 2019, 10:23:14 »
Kdyby jenom JOINy, se změnou podmínky budete muset často připojit jiné tabulky… S tím vaším přístupem, kdy chcete mít univerzální dotaz na všechno, ve kterém budete jenom měnit podmínky, byste měl udělat CROSS JOIN všech tabulek v databázi a pak si v podmínkách poskládat, co zrovna potřebujete.

Na dotaz tazatele by navrátilo identické záznamy:
SELECT * FROM tbl1 INNER JOIN tbl2 USING (id_data) WHERE allowed > 0
SELECT * FROM tbl1 LEFT OUTER JOIN tbl2 USING (id_data) WHERE allowed > 0
SELECT * FROM tbl1 INNER JOIN tbl2 ON (tbl1.id_data=tbl2.id_data AND allowed > 0)
SELECT * FROM tbl1 CROSS JOIN tbl2 WHERE tbl1.id_data=tbl2.id_data AND allowed > 0
SELECT * FROM tbl1, tbl2 WHERE tbl1.id_data=tbl2.id_data AND allowed > 0
SELECT * FROM tbl1 FULL OUTER JOIN tbl2 ON (tbl1.id_data=tbl2.id_data) WHERE allowed > 0
SELECT * FROM tbl1 FULL OUTER JOIN tbl2 ON (tbl1.id_data=tbl2.id_data AND allowed > 0)
SELECT * FROM tbl1 INNER JOIN tbl2 ON (true) WHERE tbl1.id_data=tbl2.id_data AND allowed > 0

Pouze ale jeden z těchto dotazů je sémanticky správně.

(Uvědomuji si, že MySQL nezná FULL OUTER JOIN, uvedl jsem jen pro pořádek a pro ty, co používají nějakou rozumnější databázi.)


Stran: 1 [2] 3 4 ... 137

reklama