Body zdarma Java týden
Využij podzimních slev a získej od nás až 40 % bodů zdarma! Více zde
Pouze tento týden sleva až 80 % na Java e-learning!

Diskuze: MSSQL - Inner join - Where

Aktivity (1)
Avatar
Michael K.
Člen
Avatar
Michael K.:6. května 13:00

Ahoj,

chci se zeptat - pokud použiji INNER JOIN v MSSQL dotazu a podmínku where ..

Jak to funguje z hlediska posloupnosti, co se děje v pozadí v databázi ? Řeším optimalizaci selectů.

Dejme tomu, že mám tyto tabulky (úplně zjednodušeně):
tabulka uzivatele

ID Jmeno Bydliste Oddeleni
1 Michael Třinec IT
2 Tomáš Ostrava IT
3 Roman Ostrava HR
4 Lukáš Střítež IT

tabulka faktury

ID_faktury ID_uzivatele Castka
FA1111 1 1000
FA2222 3 1599
FA3333 1 2400
FA4444 3 7249
FA5555 4 500
FA6666 2 399
FA7777 1 470
FA8888 1 1200

Pokud použiju dotaz:

SELECT * FROM faktury f
INNER JOIN uzivatele u on f.ID_Uzivatele=u.ID
WHERE u.Oddeleni= 'IT'

Jak to probíhá v pozadí ? Nejprve se udělá INNER JOIN a až poté se použije WHERE ? tzn. v pozadí by bylo 8 řádků a až poté se odfiltruje řádek s FA2222 a FA4444 ? Nebo se nejprve odfiltruje z tabulky uzivatele **Roman ? A až poté se provede **INNER JOIN ? Nevím, zda jsem dobře vysvětlil mou myšlenku, ale snad ano :)

Jde mi o to, aby zbytečně neporovnával Romana s každou fakturou i když ho nakonec podmínkou WHERE vyřadím.

Potřeboval bych zkrátka něco v tomto smyslu:

SELECT * FROM faktury f
INNER JOIN uzivatele u WHERE u.Oddeleni='IT' on f.ID_Uzivatele=u.ID
WHERE u.Bydliste = 'IT'

Děkuji :)

Zkusil jsem: U optimalizace jsem také přišel na to, že pokud selectuji pouze sloupce, které potřebuji a nepoužiji z lenosti klasiku **SELECT * **, tak je výsledek z databáze obdržen rychleji.

Chci docílit: Optimalizace SELECTu.

 
Odpovědět 6. května 13:00
Avatar
Petr Langer
Člen
Avatar
Odpovídá na Michael K.
Petr Langer:6. května 13:28

Nedávno jsem řešil něco podobného. Ten tvůj druhý dotaz bych udělal spíš takhle

SELECT * FROM faktury f
INNER JOIN uzivatele u ON f.ID_Uzivatele=u.ID AND u.Oddeleni='IT'
WHERE u.Bydliste = 'IT'

Ta druhá podmínka by taky možná šla vložit přímo do JOINU, to už si musíš vyzkoušet sám

Akceptované řešení
+20 Zkušeností
+1 bodů
Řešení problému
 
Nahoru Odpovědět  +1 6. května 13:28
Avatar
Matěj K
Člen
Avatar
Matěj K:6. května 13:31

Ahoj,

orientace zpracování dotazů funguje v tomto pořadí:
FROM, WHERE, GROUP BY, HAVING, SELECT, ORDER BY.

V tvém případě bych určitě postupoval takto:

SELECT *
FROM faktury AS f
JOIN uzivatele AS u ON f.ID_Uzivatele = u.ID
AND u.Bydliste = 'IT'

Tím se vyhneš celé klauzuli WHERE a rovnou si vyfiltruješ daný JOIN. Ze svých zkušeností a z kurzů vím, že je tato možnost nejpřesnější.

Matěj

 
Nahoru Odpovědět  +1 6. května 13:31
Avatar
Matěj K
Člen
Avatar
Matěj K:6. května 13:31

Případně si můžeš přidat i více podmínek viz:
AND u.Bydliste = 'IT' AND u.Oddeleni = 'IT'

 
Nahoru Odpovědět 6. května 13:31
Avatar
Michael K.
Člen
Avatar
Michael K.:6. května 14:11

Mám tam překlep, mělo to být WHERE u.Bydliste = 'Ostrava' jako další podmínka.

Každopádně teď zkouším a zkouším :) Nevěděl jsem, že za ON podmínka může být AND.

Tahám data ze SAP databáze, kde jsou statisíce řádků a selecty potřebuji co nejrychleji.

Jen bych se chtěl zeptat jen tak offtopic - dá se v MSSQL management studiu zjistit v záložce Results ke které tabulce daný sloupec náleží ?

Nebo zda jde zapnou jakýsi "rozdělovač", který mi ukáže ve výsledcích, kde už začíná další tabulka.

Děkuji

 
Nahoru Odpovědět 6. května 14:11
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:6. května 14:41

Ja bych sloupce pojmenoval takto, podle vyznamu

uzivatele: id_uzivatel, Jmeno, Bydliste, Oddeleni, ...
faktury: id_faktura, Castka, ...
uzivatel_faktury: id_uzivatel, id_faktura

Joiny obvykle nepouzival, jenom LEFT JOIN, ale nemel bys do selectu vypsat jmena sloupcu? Pokud se bude kryt nazev sloupce z tab a s jinym v b, tak SELECT * bude pindat error.
Nevim, jestli bych u joinu resil AND u.Bydliste = 'IT', spis bych to dal pak do where. Ale to bych musel testnout, co je rychlejsi. Teoreticky WHERE, protoze se nemusi kontrolovat join s podminkou.
A potom bych teda asi pouzil treti tabulku pro propojeni uzivatel faktura. Ale to je na uvazeni. Zhlediska rychlosti by nemel byt rozdil.

SELECT uf.id_faktura, u.jmeno, f.castka
FROM uzivatel_faktury uf
    LEFT JOIN uzivatele u ON u.id_uzivatel = uf.id_uzivatel
 -- nemusis premyslet nad nazvy sloupcu, protoze mas v obou tabulkach stejne pojmenovane sloupce
    LEFT JOIN faktury f ON f.id_faktura = uf.id_faktura
WHERE u.Oddeleni= 'IT'

Navic bych na Oddeleni udelal extra tabulku a filtroval to pomoci id, ne (u.Oddeleni= 'IT'), o.Oddeleni= 1.

Editováno 6. května 14:43
 
Nahoru Odpovědět 6. května 14:41
Avatar
Peter Mlich
Člen
Avatar
Odpovídá na Michael K.
Peter Mlich:6. května 14:55

S temi sloupci a tabulkami moc nerozumim. Ale, neznam ten program...
Select vybere data z tabulek a vrati tabulku. Ktery sloupec tam chces , v jakem poradi si definujes za SELECT slovem. Pokud tam mas *, tak to bere vsechny sloupce. Poradi tabulek bude, jake mas definovane za FROM, ne? * pouzivaji jen ti nejvetsi luzri :) Kteri si radi pridelavaji pozdeji problemy.

 
Nahoru Odpovědět 6. května 14:55
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:6. května 14:57

Mimochodem...
Co kdyby se uzivatel prestehoval? Ve starych fakturach budes mit novou adresu? To je preci spatne, ne?
A co kdyby zmenil jmeno, slecna se provda. Ve starych fakturach bude figurovat nove jmeno?
A co kdyz meni pohlavi?

 
Nahoru Odpovědět 6. května 14:57
Avatar
Peter Mlich
Člen
Avatar
Odpovídá na Peter Mlich
Peter Mlich:6. května 15:02

K tem tabulkam, znovu jsem si to precetl... V mem pripade to funguje takto:

FROM uzivatel_faktury uf
    LEFT JOIN uzivatele u ON u.id_uzivatel = uf.id_uzivatel
 -- nemusis premyslet nad nazvy sloupcu, protoze mas v obou tabulkach stejne pojmenovane sloupce
    LEFT JOIN faktury f ON f.id_faktura = uf.id_faktura

Otevri tabulku uzivatel_faktury. Ke kazdemu radu pridej data z uzivatele a z faktury (resp, on tam prida jen ukazatel/pointer databaze.tabul­ka.radek).
Ziska jednu obri tabulku. Poradi radku bude podle tabulky uzivatel_faktury.
A na zaver posklada data do tabulky podle toho, co mas v SELECT. Jestli tam mas GROUP BY, WHERE a tak, tak to filtruje.

Jo, jestli chces mit na konci nejake poradi, zkus pouzit ORDER BY (mysql), v msql nevim. Tam se ale tusim pise jinak jen LIMIT.

Editováno 6. května 15:04
 
Nahoru Odpovědět 6. května 15:02
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 9 zpráv z 9.