Vývojářský blog Tomáše Hercega

Tisk článku Tisk článku

Jednoduchá SQL hádanka

[Zpět na blog]

Datum: 29. 7. 2009 12:19       Autor: Tomáš Herceg       Zobrazeno: 1125x

Kategorie: SQL


O víkendu jsem narychlo musel dělat jeden projekt a během něj jsem narazil na poměrně zajímavý problém. Máte tabulku se dvěma sloupci - Skupina a Datum. V každé skupině je několik datumů, takže tabulka má třeba 100 řádků, je v ní 10 různých skupin a v každé skupině je několik různých dat. Potřeboval jsem v databázi vybrat z každé skupiny třeba 5 nejnižších datumů a ideálně to celé chroupnout do 1 selectu, abych to nevybíral pro každou skupinu zvlášť (skupin jsou stovky, bylo by to pomalé). Otázkou je, jak tedy v MS SQL Serveru vybrat prvních n záznamů z každé skupiny (podle data) tak, abych pro každou skupinu nedělal separátní select. Abych to trochu zjednodušil, ten select nemusí být jeden, ale musí jich být konstantně mnoho - počet selectů nesmí záviset na počtu skupin ani na velikosti n (kolik záznamů z každé skupiny chceme).

Protože o víkendu, kdy jsem měl naspěch, mě inteligentní řešení na úrovni SQL nenapadlo, udělal jsem to na klientovi. Dnes ráno jsem si ale vzpomněl na jedno klíčové slovo v SQL, o kterém jsem věděl, ale vůbec jsem si neuvědomil, že bych ho měl použít.

Můžete použít tato testovací data (místo datumu jsem tam dal čísla, to je jedno, ono to vyjde nastejno):

-- testovací data
DECLARE @t TABLE ([CategoryId] INT, [Number] INT)
INSERT INTO @t VALUES (1, 1)
INSERT INTO @t VALUES (1, 4)
INSERT INTO @t VALUES (1, 7)
INSERT INTO @t VALUES (1, 15)
INSERT INTO @t VALUES (1, 26)
INSERT INTO @t VALUES (1, 27)
INSERT INTO @t VALUES (1, 48)
INSERT INTO @t VALUES (2, 1)
INSERT INTO @t VALUES (2, 5)
INSERT INTO @t VALUES (2, 9)
INSERT INTO @t VALUES (2, 10)
INSERT INTO @t VALUES (2, 15)
INSERT INTO @t VALUES (3, 1)
INSERT INTO @t VALUES (3, 2)
INSERT INTO @t VALUES (3, 3)
INSERT INTO @t VALUES (4, 1)
INSERT INTO @t VALUES (4, 4)
INSERT INTO @t VALUES (4, 8)
INSERT INTO @t VALUES (4, 13)
INSERT INTO @t VALUES (4, 20)
INSERT INTO @t VALUES (4, 95)

Z každé skupiny CategoryId chci vybrat 4 nejnižší hodnoty Number. Pokud je ve skupině záznamů méně, pochopitelně vybíráme celou skupinu. Výsledek by měl vypadat takto:

Výsledek

Svoje řešení zasílejte na e-mailovou adresu string.Format(“{0}@{1}.{2}”, “herceg”, “vbnet”, “cz”).


> Na začátek

 

Hodnocení:

Hlasů: 0
Zvolte své hodnocení

Tomáš Herceg

Autor pochází z Třebíče, kde vystudoval osmileté gymnázium, nyní je studentem druhého ročníku bakalářského studia Matematicko-fyzikální fakulty Univerzity Karlovy v oboru Informatika. Programování se věnuje velmi dlouho a kromě počítačů patří mezi jeho záliby také hra na klavír a matematika. V poslední době tráví většinu času psaním aplikací v jazyce C#, Visual Basic .NET a v ASP.NET.

Podpořte vznik dalších článků
RSS Feed RSS Feed

Diskuse

1 

n hodnot pomocí T-SQL

Datum: 8.8.2009 11:04
Autor: Petr Zajíc
Hodnocení autora: 88
Příspěvků: 198
Řešení je třeba v jedné knížce o T-SQL, ale nechci luštitelům kazit radost, tak neprozradím ve které ;-)
 
           [Odpovědět]
 
Hodnocení: 0 Čekejte, prosím...

reseni

Datum: 1.2.2010 22:27
Autor: neregistrovaný (90.181.50.71)
Hodnocení autora: není
Příspěvků: 0


select 
	tmp.[CategoryId], 
	tmp.Number 
from
	(select 
		[CategoryId], 
		[Number], 
		dense_Rank() over (Partition BY [CategoryId] order by [Number] ASC) as DRank
	from @t) tmp
where tmp.DRank < 5
 
 
           [Odpovědět]
 
Hodnocení: 0 Čekejte, prosím...

Re: reseni

Datum: 1.2.2010 22:35
Autor: Tomáš Herceg
Hodnocení autora: 999
Příspěvků: 2400
Sice půl roku po termínu, ale správně.
 
           [Odpovědět]
 
Hodnocení: 0 Čekejte, prosím...
1 
 

VBNET.CZ | © 2007 Tomáš Herceg, Tomáš Jecha | Kopírování a přejímání jakéhokoliv obsahu z tohoto webu je bez písemného svolení autorů zakázáno.