Tento blog je v současné době uzavřen.
Pokračování blogu na bloguje.cz jsem zrušil. Pokud budu někdy pokračovat, bude to spíš tady.
Do tabulky databáze opakovaně zaznamenávám výskyt objektu a nějaké jeho charakteristiky. Zajímá mě, jestli se (třeba v určitém časovém rozmezí) objekt vyskytoval pokaždé se stejnou charakteristikou. Sleduju třeba jméno uživatele a jeho IP adresu (nebo třeba nějaké jeho nastavení). Zajímá mě, jestli k jednomu uživateli mám, třeba i opakovaně, pořád stejné IP (nebo prostě ten druhý údaj).
Dejme tomu, že mám tabulku tabulka, která má pole id (identifikuje objekt) a vlastnost (charakteristika objektu).
Jednou z možností je řešit celý problém ve dvou krocích (tj. poddotazem). V tabulce se seskupí všechny kombinace výskytu polí id a vlastnost:
SELECT DISTINCTROW id, vlastnost FROM tabulka;
Načež řádky výše uvedeného dotazu seskupím podle id a zjistím, která id se vyskytují ve více řádcích:
SELECT id, count(*) AS pocet FROM (SELECT DISTINCTROW id, vlastnost FROM tabulka) AS poddotaz GROUP BY id HAVING pocet>1;
Řešení pomocí jednoho dotazu vychází z oblíbeného triku, kdy se tabulka propojí se sebou samotnou. Hledám případy, kdy se objekt (uživatel) vyskytuje v tabulce s různými hodnotami charakteristiky. Tedy si vyhledám dvojice záznamů, které mají stejného uživatele, ale jinou charakteristiku:
SELECT a.id AS id FROM tabulka AS a JOIN tabulka AS b ON (a.id=b.id And a.vlastnost<>b.vlastnost);
Takhle by mi dotaz vypsal všechna id, která mají v tabulce různé hodnoty pole vlastnost. Ovšem vypsal by mi je opakovaně, pro každou nalezenou dvojici hodnot charakteristiky dvakrát. Opakování se ovšem snadno odstraní doplněním DISTINCTROW:
SELECT DISTINCTROW a.id AS id FROM tabulka AS a JOIN tabulka AS b ON (a.id=b.id And a.vlastnost<>b.vlastnost);
A pokud chci vypsat ke každému objektu, u něhož se hodnota charakteristiky změnila, všechny nalezené hodnoty charakteristik, přidám do výpisu ještě jedno z polí a.vlastnost, b.vlastnost (je to jedno) a uspořádám si výpis:
SELECT DISTINCTROW a.id AS id, a.vlastnost AS vlastnost FROM tabulka AS a JOIN tabulka AS b ON (a.id=b.id And a.vlastnost<>b.vlastnost) ORDER BY id, vlastnost;
Proč vůbec píšu o napohled složité konstrukci pro jediný dotaz, když poddotaz vypadá elegantněji a u větších tabulek je méně náročný? Protože:
Máte-li vhodnou konstelaci hvězd, databáze a tabulek, klidně používejte poddotazy a tento článek berte jako kuriozitu ;-)
Další články si můžete vyhledat v jednotlivých přihrádkách, případně podle data.
© Honza Hučín 2004–6
Šuplík běží na PIPNI.CZ. Díky!
8. 8. 16:48 | Pepa
7. 8. 21:26 | Honza Hučín
7. 8. 21:02 | Honza
6. 8. 14:29 | Pepa
3. 8. 18:29 | Honza
*1967, absolvent MFF UK v Praze (1991)
statistik, analytik, programátor, učitel, hudebník