Poslední úpravy - Vyhledat:

SQL

O modelování

Power Designer

Oracle Data Modeler

Zdroje...

edit SideBar

SQL /

Co v databázi není?

< Poddotazy | SQL postupně | UNION dotazy >

I informace, že záznamy s nějakými vlastnostmi v databázi nejsou, je užitečná. Například se můžeme ptát jestli někdy došlo ke zlevnění nějakého zboží: ptáme se zda existují v tabulce POLOZ dva různé záznamy se stejným kódem zboží, druhý s číslem objednávky pozdějším než v prvním záznamu, a s VCEN/MNOZ menším.


Příklad: Existuje dvojice objednávek stejného zboží, první dříve než druhá, s jednotkovou cenou menší v pozdější objednávce?

        select PRV.CISO,DRU.CISO,KOD
        from POLOZ PRV join POLOZ DRU using (KOD)
        where PRV.CISO<DRU.CISO
         and  PRV.VCEN/PRV.MNOZ>DRU.VCEN/DRU.MNOZ;
Negativní odpověď nám říká, že ke zlevnění asi nikdy nedošlo, alespoň co se týče uskutečněných objednávek.

Typický případ je, že hledáme exempláře nějakého typu, pro něž neexistuje v databázi související záznam nějakých vlastností. Například se ptáme, zda existuje zboží, jež nebylo nikdy objednáno, a případně jaké je to zboží. Množství následujících příkladů vám poskytne návod:

Příklad: Které zboží nebylo objednáno v žádné objednávce?

        select KOD, NAZ
        from ZBOZ left join POLOZ using (KOD)
        where CISO is null;
Nebo jinak:
        select KOD, NAZ
        from ZBOZ
        where KOD not in (select KOD from POLOZ);
Nebo:
        select KOD, NAZ
        from ZBOZ
        where not exists (select * from POLOZ where POLOZ.KOD=ZBOZ.KOD);

Která z předchozích formulací je nejlepší? Odpověď závisí na možnostech optimalizátoru, v ideálním případě jsou stejné. První formulce však poskytuje nejlepší možnosti optimalizace, lze ji tedy doporučit. Zato poslední, s korelovaným poddotazem, nutí databázový engine vykonávat operace v určitém pořadí, tedy jsou v tomto případě možnosti optimalizace nejhorší. Podobně je tomu s dalšími příklady:

Příklad: Které zboží nebylo objednáno v roce 2009?

        select ZBOZ.KOD, NAZ
        from ZBOZ left join (POLOZ join OBJ using (CISO) ) on (POLOZ.KOD=ZBOZ.KOD and extract(year from DAT)=2009) 
        where CISO is null;
Nebo jinak:
        select KOD, NAZ
        from ZBOZ
        where KOD not in (select KOD from POLOZ join OBJ using (CISO) where extract(year from DAT)=2009);
Nebo:
        select KOD, NAZ
        from ZBOZ
        where not exists (select * from POLOZ join OBJ using (CISO) where ZBOZ.KOD=POLOZ.KOD and extract(year from DAT)=2009);

Příklad: Který zákazník nemá žádnou objednávku?

        select LOG
        from ZAK left join OBJ on (LOG=ZAK)
        where CISO is null;
Nebo jinak:
        select LOG
        from ZAK
        where LOG not in (select ZAK from OBJ);
Nebo:
        select KOD, NAZ
        from ZAK
        where not exists (select * from OBJ where ZAK=LOG);

Příklad: Který zákazník nemá žádnou objednávku do osobního převzetí?

        select LOG
        from ZAK left join OBJ on (LOG=ZAK and DOPR=1)
        where CISO is null;
Nebo jinak:
        select LOG
        from ZAK
        where LOG not in (select ZAK from OBJ where DOPR=1);
Nebo:
        select KOD, NAZ
        from ZAK
        where not exists (select * from OBJ where ZAK=LOG and DOPR=1);

Příklad: Která kategorie namá žádné podkategorie?

        select NAD.KAT
        from KAT NAD left join KAT POD on (NAD.KAT=POD.NADR)
        where POD.KAT is null;
Nebo jinak:
        select KAT
        from KAT
        where KAT not in (select NADR from KAT where NADR is not null);
Narozdíl od předchozích příkladů, zde připadá do úvahy NULL hodnota v porovnávaném sloupci (NADR). Další možnost:
        select KAT
        from KAT NAD
        where not exists (select * from KAT POD where NAD.KAT=POD.NADR);

Příklad: Ve které kategorii není žádné zboží?

        select KAT
        from KAT left join ZBOZ using (KAT)
        where KOD is null;
Nebo jinak:
        select KAT
        from KAT
        where KAT not in (select KAT from ZBOZ);
Nebo:
        select KAT.KAT
        from KAT
        where not exists (select * from ZBOZ where ZBOZ.KAT=KAT.KAT);

Příklad: Ve které kategorii není žádné aktivní zboží?

        select KAT.KAT
        from KAT left join ZBOZ on (KAT.KAT=ZBOZ.KAT and AKTI=0)
        where KOD is null;
Nebo jinak:
        select KAT.KAT
        from KAT
        where KAT not in (select KAT from ZBOZ where AKTI=0);
Nebo:
        select KAT.KAT
        from KAT
        where not exists (select * from ZBOZ where ZBOZ.KAT=KAT.KAT and AKTI=0);

< Poddotazy | SQL postupně | UNION dotazy >

Upravit - Historie - Tisk - Poslední úpravy - Vyhledat
Poslední úprava stránky: 20.10.2009, 19:42