November 25, 2004 at 3:51 am
Dear all,
I have the following table:
field name (of varchar(10))
field date (of datetime, default getdate())
Each value of name can come up more than once in the table.
I am looking for a tsql statement to give me the following result:
the first 10 rows of a table, for each of the names in the table.
I hope I have explained it well enough.
regards,
Hans
November 25, 2004 at 5:29 am
Actually there is no such thing as "the first 10 rows". If I understand you right, you have two alternatives:
USE PUBS
GO
SET ROWCOUNT 10
SELECT au_lname FROM authors ORDER BY au_lname
SET ROWCOUNT 0
--or
SELECT TOP 10 au_lname FROM authors ORDER BY au_lname
--
Frank Kalis
Microsoft SQL Server MVP
Webmaster: http://www.insidesql.org/blogs
My blog: http://www.insidesql.org/blogs/frankkalis/[/url]
November 25, 2004 at 5:55 am
Thank you for your answer Frank. Indeed what I ment was the top 10 of the table, but then per name.
For the following example not to take up too much space, I limit the amount to 2 rows per name.
Table1 consists of the foillowing data:
name date
Arley 02-3-2004
Arley 10-3-2004
Arley 12-3-2004
Arley 01-3-2004
Ben 10-3-2004
Ben 17-3-2004
Ben 03-3-2004
I need a query that gives the following result:
name date
Arley 12-3-2004
Arley 10-3-2004
Ben 17-3-2004
Ben 10-3-2004
So for each name present the query should show the top 2 rows (ordered by date desc)
I hope this examples clarifies the question a bit.
regards,
Hans
November 25, 2004 at 6:24 am
Okay, what about:
set nocount on
create table hans
(
name varchar(10)
, date datetime default getdate()
)
insert into hans (name, date) values('Arley','20040302')
insert into hans (name, date) values('Arley','20040310')
insert into hans (name, date) values('Arley','20040312')
insert into hans (name, date) values('Arley','20040301')
insert into hans (name, date) values('Ben','20040310')
insert into hans (name, date) values('Ben','20040317')
select
t1.name
, t1.date
from
hans t1
where
t1.date in
(
select top 2 with ties
t2.date
from
hans t2
where
t2.name = t1.name
order by
t2.date desc
)
order by
t1.name
, t1.date desc
drop table hans
set nocount off
name date
---------- ------------------------------------------------------
Arley 2004-03-12 00:00:00.000
Arley 2004-03-10 00:00:00.000
Ben 2004-03-17 00:00:00.000
Ben 2004-03-10 00:00:00.000
--
Frank Kalis
Microsoft SQL Server MVP
Webmaster: http://www.insidesql.org/blogs
My blog: http://www.insidesql.org/blogs/frankkalis/[/url]
November 25, 2004 at 6:26 am
Oh, and may I add that you shouldn't use use words as name and date as identifiers for column?
--
Frank Kalis
Microsoft SQL Server MVP
Webmaster: http://www.insidesql.org/blogs
My blog: http://www.insidesql.org/blogs/frankkalis/[/url]
November 25, 2004 at 12:44 pm
Yes, I will check on this.
Frank, how would the query be if I have more than 2 different names? If the number of different names is dynamic, can I still use the construction that you showed me?
regards,
Hans
November 25, 2004 at 1:03 pm
No need to worry!
Have a play with it and you'll see
set nocount on
create table hans
(
name varchar(10)
, date datetime default getdate()
)
insert into hans (name, date) values('Arley','20040302')
insert into hans (name, date) values('Arley','20040310')
insert into hans (name, date) values('Arley','20040312')
insert into hans (name, date) values('Arley','20040301')
insert into hans (name, date) values('Frank','20040310')
insert into hans (name, date) values('Ben','20040317')
select
t1.name
, t1.date
from
hans t1
where
t1.date in
(
select top 2 with ties
t2.date
from
hans t2
where
t2.name = t1.name
order by
t2.date desc
)
order by
t1.name
, t1.date desc
drop table hans
set nocount off
name date
---------- ------------------------------------------------------
Arley 2004-03-12 00:00:00.000
Arley 2004-03-10 00:00:00.000
Ben 2004-03-17 00:00:00.000
Frank 2004-03-10 00:00:00.000
This should work on as many distinct names as you have in your table.
--
Frank Kalis
Microsoft SQL Server MVP
Webmaster: http://www.insidesql.org/blogs
My blog: http://www.insidesql.org/blogs/frankkalis/[/url]
November 26, 2004 at 2:55 pm
how does the "with ties" work in this situation? I've yet to ever find a need for that feature, but I am wondering if perhaps I've just found more difficult ways of acheiving the same solution.
Cheers,
Quentin
November 29, 2004 at 1:31 am
The WITH TIES is not really needed in this situation, I think, because of the combination of ...IN... TOP 2 ... WITH TIES. If you have two or more rows with the same date and this date falls within the TOP 2 it will be handled by the IN condition anyway. Here's a maybe better example of what WITH TIES does:
SET NOCOUNT ON
DECLARE @TTT TABLE
(
THE_ID INT NOT NULL
, Name varchar(50)
)
INSERT INTO @TTT VALUES(1,'A');
INSERT INTO @TTT VALUES(2,'BB');
INSERT INTO @TTT VALUES(2,'B');
INSERT INTO @TTT VALUES(3,'C');
INSERT INTO @TTT VALUES(3,'D');
INSERT INTO @TTT VALUES(3,'DD');
INSERT INTO @TTT VALUES(3,'DDD');
INSERT INTO @TTT VALUES(3,'DDDD');
INSERT INTO @TTT VALUES(4,'E');
INSERT INTO @TTT VALUES(5,'F');
INSERT INTO @TTT VALUES(6,'G');
SET NOCOUNT OFF
SELECT TOP 4
THE_ID
FROM
@TTT
ORDER BY
1;
SELECT TOP 4 WITH TIES
THE_ID
FROM
@TTT
ORDER BY
1;
SELECT DISTINCT TOP 4
THE_ID
FROM
@TTT
ORDER BY
1;
Got this from a posting here by Len Esterhuyse.
--
Frank Kalis
Microsoft SQL Server MVP
Webmaster: http://www.insidesql.org/blogs
My blog: http://www.insidesql.org/blogs/frankkalis/[/url]
November 29, 2004 at 2:35 am
But what if the dates are so randomly distributed that no date is the same?
Anyway, this concept worked like a charm for the statement I was looking for.
May I thank you very much Frank
high regards,
Hans
November 29, 2004 at 2:37 am
>But what if the dates are so randomly distributed that no date is the same?
In this case you'll find that you get two rows per name as requested.
--
Frank Kalis
Microsoft SQL Server MVP
Webmaster: http://www.insidesql.org/blogs
My blog: http://www.insidesql.org/blogs/frankkalis/[/url]
November 29, 2004 at 2:46 am
But only if I use 'WITH TIES'?!
The other thing is that TOP 2 could also be TOP 5, or TOP 20 (I want to fill in a number for this, to make the query dynamic).
Hans
November 29, 2004 at 3:30 am
But only if I use 'WITH TIES'?!
No, sorry if I confused you. Forget the WITH TIES in your case. It is redundant.
As for making it dynamic:
See http://www.sommarskog.se/dynamic_sql.html and http://www.sommarskog.se/dyn-search.html for very detailed informations and examples on how to accomplish this.
--
Frank Kalis
Microsoft SQL Server MVP
Webmaster: http://www.insidesql.org/blogs
My blog: http://www.insidesql.org/blogs/frankkalis/[/url]
August 18, 2012 at 3:31 am
--Generate some data
--Generate some data
SELECT d.*
,IDENTITY (INT, 1,1) AS Row
INTO #Tmp
FROM (
SELECT CONVERT(VARCHAR(10),'A') AS Name,CONVERT(DATETIME,DATEADD(d,1,GETDATE())) AS TheDate UNION ALL
SELECT 'A',DATEADD(d,2,GETDATE()) UNION ALL
SELECT 'A',DATEADD(d,2,GETDATE()) UNION ALL
SELECT 'A',DATEADD(d,4,GETDATE()) UNION ALL
--SELECT 'A',DATEADD(d,5,GETDATE()) UNION ALL
SELECT 'B',DATEADD(d,1,GETDATE()) UNION ALL
--SELECT 'B',DATEADD(d,2,GETDATE()) UNION ALL
--SELECT 'B',DATEADD(d,3,GETDATE()) UNION ALL
--SELECT 'B',DATEADD(d,4,GETDATE()) UNION ALL
--SELECT 'B',DATEADD(d,5,GETDATE()) UNION ALL
SELECT 'C',DATEADD(d,1,GETDATE()) UNION ALL
--SELECT 'C',DATEADD(d,2,GETDATE()) UNION ALL
--SELECT 'C',DATEADD(d,3,GETDATE()) UNION ALL
SELECT 'C',DATEADD(d,4,GETDATE()) UNION ALL
SELECT 'C',DATEADD(d,5,GETDATE())
) AS d
ORDER BY Name,TheDate
--If many rows
CREATE INDEX INDXTmp ON #Tmp(Name,Row)
--Get first three rows per name
SELECT t.Name,t.TheDate
FROM #Tmp t
WHERE t.ROW BETWEEN (SELECT MIN(tt.Row) FROM #Tmp tt WHERE tt.Name=t.Name)
AND (SELECT MIN(ttt.Row) FROM #Tmp ttt WHERE ttt.Name=t.Name)+2
ORDER BY t.Name,t.TheDate
DROP TABLE #Tmp
Viewing 14 posts - 1 through 13 (of 13 total)
You must be logged in to reply to this topic. Login to reply