Šuplík Honzy Hučína

Skok na navigaci (menu)

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.

Jednotlivý článek

Internet a vše kolem
12. 8. 2005

Kontrola unikátnosti jedním SQL dotazem

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).

Nejprve řešení poddotazem

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í jedním dotazem

Ř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;

Jeden krok, nebo dva?

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:

  • poddotazy v některých verzích databází nefungují (v MySQL až od verze 4.1),
  • některé způsoby výpisu se pomocí poddotazu zařídí obtížně,
  • je to zajímavý oříšek na přemýšlení.

Máte-li vhodnou konstelaci hvězd, databáze a tabulek, klidně používejte poddotazy a tento článek berte jako kuriozitu ;-)

Komentáře (počet: 5, poslední 18. 8. 2005, 14:14, nelze přidat komentář)
RSS komentářů tohoto článku
Trvalý odkaz

Poslední články:

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!

sber.cermat.cz

RSS Šuplíku

RSS komentářů – souhrnně

U každého článku je samostatný RSS kanál pro komentáře.

Výběr článků

Posledních 10 článků

nebo podle data:

nebo hledání fulltextem:

Archiv všech článků

Poslední komentáře

Zabili mě, parchanti [2]

8. 8. 16:48 | Pepa

Cestou kolem blogu [2]

7. 8. 21:26 | Honza Hučín

Cestou kolem blogu [1]

7. 8. 21:02 | Honza

Vrtulník nad hlavou [3]

6. 8. 14:29 | Pepa

Taková hra na volby [1]

3. 8. 18:29 | Honza

Nejčtenější

Žádné údaje nejsou k dispozici.

O mně

*1967, absolvent MFF UK v Praze (1991)

statistik, analytik, programátor, učitel, hudebník

nyní Ústav pro informace ve vzdělávání

Životopis (RTF)

Napište mi