IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Diskuze: vnorený SELECT s DISTINCT-om

V předchozím kvízu, Online test znalostí SQL a databází, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
JanekV
Člen
Avatar
JanekV:25.8.2020 10:40

Potrebujem vytvorit dotaz zo vstupnej tabulky :

id      cislo   uzivatel                datum

1       001     user1           2020-01-01 00:01
2       001     user1           2020-01-01 00:02
3       002     user1           2020-01-01 00:03

4       001     user2           2020-01-01 00:04
5       001     user2           2020-01-01 00:05
6       002     user2           2020-01-01 00:06

7       001     user3           2020-01-01 00:07
8       001     user3           2020-01-01 00:08
9       002     user3           2020-01-01 00:09

Zkusil jsem: Skusal som rozne kombinacie s DISTINCT, ale v SQL viem iba zaklady a nedokazem dat dohromady pozadovany SELECT

Chci docílit: Vystupna tabulka ma zobrazit vsetkych userov ktory mali cislo 001 ( to by bolo lahke ) a kedy sa prvykrat prihlasili.
T.j. nieco taketo :

1       001     user1   2020-01-01 00:01
4       001     user2   2020-01-01 00:04
7       001     user3   2020-01-01 00:07

Diky za kazde nasmerovanie k vysledku :-)

Editováno 25.8.2020 10:42
 
Odpovědět
25.8.2020 10:40
Avatar
Odpovídá na JanekV
Michal Štěpánek:25.8.2020 12:22

Když za to tvé "lehké" přidáš GROUP BY uzivatel ORDER BY datum, měl bys dostat po čem toužíš...
např.

SELECT * FROM tabulka WHERE cislo = @cislo GROUP BY uzivatel ORDER BY datum
Nahoru Odpovědět
25.8.2020 12:22
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
JanekV
Člen
Avatar
Odpovídá na Michal Štěpánek
JanekV:25.8.2020 13:35

Dík, ale to nepôjde
"Column 'tabulka.id' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause."

Ja som skúšal spraviť si iba zoznam userov bez duplicít, ktorí mali dané číslo

SELECT DISTINCT uzivatel FROM tabulka WHERE cislo = @cislo ORDER BY uzivatel

a potom druhú tabuľku, kde sa vyberie iba prvý záznam usera s predch.tabuľky a daným číslom. Toto spraviť nejakým vnoreným SELECTom.. nieje to moc zrozumiteľné, ale asi vieš o čo ide aký chcem výsledok.

 
Nahoru Odpovědět
25.8.2020 13:35
Avatar
Odpovídá na JanekV
Michal Štěpánek:25.8.2020 14:05

Logicky slovo "tabulka" musíš nahradit názvem své tabulky...

Nahoru Odpovědět
25.8.2020 14:05
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
JanekV
Člen
Avatar
Odpovídá na Michal Štěpánek
JanekV:25.8.2020 14:31

:) to je jasné, až taký začiatočník nie som. MS-SQL to skrátka nechce takto zoskupovať.

 
Nahoru Odpovědět
25.8.2020 14:31
Avatar
Odpovídá na JanekV
Michal Štěpánek:25.8.2020 14:33

Tak si přečti tu chybu a jednoduše místo hvězdičky tam ty sloupce vypiš...

Nahoru Odpovědět
25.8.2020 14:33
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Jakub Švasta
Lektor
Avatar
Odpovídá na JanekV
Jakub Švasta:25.8.2020 17:15

Pokud ti stačí jen uživatel a datum, dá se použít agregační funkce MIN:

SELECT uzivatel, MIN(datum) AS prvni_login FROM tabulka WHERE cislo = @cislo GROUP BY uzivatel ORDER BY uzivatel

Pokud bys potřeboval celý záznam i s id, pak už na to funkce MIN nestačí, protože vrací jen nejmenší hodnotu v daném sloupci, ale už ne id příslušného záznamu. Ale šlo by to takhle:

SELECT Tvnejsi.*
FROM tabulka Tvnejsi
OUTER APPLY
(
        SELECT TOP 1 Tvnitrni.id FROM tabulka Tvnitrni WHERE Tvnitrni.uzivatel = Tvnejsi.uzivatel AND Tvnitrni.cislo = @cislo ORDER BY Tvnitrni.datum
) AS Pomoc
WHERE Tvnejsi.id = Pomoc.id
ORDER BY Tvnejsi.uzivatel

Princip v tom druhém případě je takový, že ke každému záznamu tabulky nejdřív připojíš id odpovídající správnému datumu. To se dělá pomocí toho OUTER APPLY. Konstrukce OUTER APPLY je vlastně totéž jako JOIN, akorát ti umožňuje odvolávat se uvnitř na vnější tabulku. Uvnitř outer apply zavoláš vlastní logiku - že číslo musí být @cislo a že pro daného uživatele tě zajímá jen první záznam podle data. Zároveň uvnitř musí být vazba Tvnitrni.uzivatel = Tvnejsi.uzivatel, abys uvnitř prohledával záznamy jen pro správného uživatele. A když už máš k vnější tabulce připojená správná id, už jen řekneš, že ostatní záznamy tě nezajímají (to je to WHERE Tvnejsi.id = Pomoc.id).

Pro lepší názornost jsem připojil obrázek, kde ukazuju i mezivýsledek. Ten pátý sloupec v mezivýsledku jsou právě ta správná id připojená ke všem záznamům původní tabulky. Toho zavináče v @tabulka si nevšímej, to je jen moje deklarovaná tabulka, pomocí které emuluju tu tvoji.

Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
 
Nahoru Odpovědět
25.8.2020 17:15
Avatar
JanekV
Člen
Avatar
JanekV:26.8.2020 21:39

Páni dík za odpovede a Jakub Švasta za super vysvetlenie. Presne takúto nejakú konštrukciu som hľadal a na základe nej môžem poriešiť daľšie dotazy ktoré potrebujem. Ešte raz veľké DÍK.

 
Nahoru Odpovědět
26.8.2020 21:39
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 8 zpráv z 8.