Autor Zpráva
MaK
Profil
Mám dvě tabulky:

CREATE TABLE aaa SELECT * FROM (VALUES ROW(1), ROW(2), ROW(3)) AS dt(a);
CREATE TABLE bbb SELECT * FROM (VALUES ROW(1,7,0), ROW(2,7,0), ROW(3,8,0)) AS dt(a,b,c);

Zadaní je: Vypiš všechny řádky z tabulky aaa, pro ktere NEEXISTUJE záznam bbb(a, b=10, c=*)
Očekávaný výsledek: Řádky 1,2,3, neboť v bbb neexistují řádky 1,10,*, ani 2,10,* ani 3,10,*

Mám dva dotazy, o kterých jsem se domníval, že mají být identické.

-- vysledek: nula radku
SELECT aaa.a
FROM aaa
LEFT JOIN bbb USING (a) 
WHERE 
    bbb.b = 10
AND bbb.c IS NULL; 

-- vysledek: radky 1,2,3
SELECT aaa.a
FROM aaa
LEFT JOIN bbb ON (bbb.a = aaa.a AND bbb.b = 10) 
WHERE 
      bbb.c IS NULL; 

Pokud by někoho zajímal EXPLAIN:

-- prvni dotaz 
select `test`.`aaa`.`a` AS `a` from `test`.`aaa` join `test`.`bbb` where ((`test`.`aaa`.`a` = `test`.`bbb`.`a`) and (`test`.`bbb`.`b` = 10) and (`test`.`bbb`.`c` is null))

-- druhy dotaz 
select `test`.`aaa`.`a` AS `a` from `test`.`aaa` left join `test`.`bbb` on(((`test`.`bbb`.`b` = 10) and (`test`.`bbb`.`a` = `test`.`aaa`.`a`))) where (`test`.`bbb`.`c` is null)

Proč se v prvním dotazu LEFT JOIN přeměnil na JOIN (viz explain). Proč nejsou oba dotazy identické?


MaK
Firibix
Profil
Reakce na MaKa:
Proč se v prvním dotazu LEFT JOIN přeměnil na JOIN (viz explain). Proč nejsou oba dotazy identické?
Kvůli WHERE klauzuli v prvním dotazu. Vybíráš řádky s bbb.b = 10, což nutně eliminuje NULL hodnoty z chybějících řádků v tabulce bbb a dotaz se může zoptimalizovat na INNER JOIN.
Keeehi
Profil
Protože ten první dotaz nedělá vůbec to co chceš. Jak si představuješ že by měla fungovat podmínka bbb.b = 10 AND bbb.c IS NULL. Tydle dvě podmínky v tvém příkladu nemůžou nikdy platit společně.

Ještě by byla varianta s poddotazem.
SELECT *
FROM aaa
WHERE
    a NOT IN (
        SELECT
            a
        FROM
            bbb
        WHERE
           b = 10
    )
MaK
Profil
Myslel jsem, tak nějak automaticky, že když u JOIN mohu uvést některé parametry spojení do WHERE, že si to samé mohu dovolit i u LEFT JOIN. Jak se zdá, tak u LEFT JOIN je třeba vše uvést do USING/ON.

Děkuji.

MaK

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0