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: 1651x

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

Pocházím z Třebíče, kde jsem vystudoval osmileté gymnázium, nyní jsem studentem třetího ročníku bakalářského studia Matematicko-fyzikální fakulty Univerzity Karlovy v oboru Informatika. Programování se věnuji velmi dlouho a kromě počítačů patří mezi mé záliby také hra na klavír a golf. V poslední době trávím 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: 95
Příspěvků: 223
Ř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: 1170
Příspěvků: 2746
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.