June 8, 2010 at 3:15 am
There is a table named "fathers" which has two columns:FatherName and DaughterAge
Records are like this:
Father1 12
Father1 17
Father2 22
Father3 15
Father3 17
Father3 19
So father1 has 2 daughters aged 12 and 17 and Father3 has 3 & so on....
I want one row for each father showing their eldest daughter age. sth like this:
Father1 17
Father2 22
Father3 19
BUT I DONT WANT TO USE A GROUP BY in the query for some specific reason.
Any help???
Online Trainer For SQL DBA and Developer @RedBushTechnologies with 18 yrs exp.
June 8, 2010 at 3:36 am
Hey there, try this :
DECLARE @Fathers TABLE (FatherId VARCHAR(10), age INT)
INSERT INTO @Fathers
SELECT 'Father1', 12
UNION ALL SELECT 'Father1', 17
UNION ALL SELECT 'Father2', 22
UNION ALL SELECT 'Father3', 15
UNION ALL SELECT 'Father3', 17
UNION ALL SELECT 'Father3', 19
;WITH CTE AS
(
SELECT ROW_NUMBER() OVER(PARTITION BY FatherId ORDER BY age DESC ) RN , * FROM @Fathers
)
SELECT * FROM CTE WHERE RN = 1
June 8, 2010 at 3:38 am
As this is fairly simple to construct, i myself created the sample data and scripts and the code.. in future, u can follow what Jan Van said and post data in readily consumable format, so that every one will give it a shot..
June 8, 2010 at 3:46 am
This should work for you.
--First things first, since you have provided this in your question,
--I build some dummy data.
DECLARE @Table1 TABLE(
[Father] VARCHAR(50),
[Oldest Daughter] INT)
INSERT INTO @Table1
VALUES ('Father1',12)
INSERT INTO @Table1
VALUES ('Father1',17)
INSERT INTO @Table1
VALUES ('Father2',22)
INSERT INTO @Table1
VALUES ('Father3',15)
INSERT INTO @Table1
VALUES ('Father3',17)
INSERT INTO @Table1
VALUES ('Father3',19)
--Now for the query
SELECT t1.*
FROM @Table1 AS t1
LEFT OUTER JOIN @Table1 AS t2
ON ( t1.[Father] = t2.[Father]
AND t1.[Oldest Daughter] < t2.[Oldest Daughter] )
WHERE t2.[Oldest Daughter] IS NULL;
June 8, 2010 at 4:07 am
Why make it that complicated?
DECLARE @Fathers TABLE (FatherId VARCHAR(10), age INT)
INSERT INTO @Fathers
SELECT 'Father1', 12
UNION ALL SELECT 'Father1', 17
UNION ALL SELECT 'Father2', 22
UNION ALL SELECT 'Father3', 15
UNION ALL SELECT 'Father3', 17
UNION ALL SELECT 'Father3', 19
SELECT FatherId, MAX ( age ) AS 'age'
FROM @Fathers
GROUP BY FatherId
Or am I missing something?
June 8, 2010 at 4:24 am
DECLARE @Fathers TABLE (FatherId VARCHAR(10), age INT)
INSERT INTO @Fathers
SELECT 'Father1', 12
UNION ALL SELECT 'Father1', 17
UNION ALL SELECT 'Father2', 22
UNION ALL SELECT 'Father3', 15
UNION ALL SELECT 'Father3', 17
UNION ALL SELECT 'Father3', 19
-- GROUP BY disallowed (probably homework)
--SELECT FatherId, MAX ( age ) AS 'age'
--FROM @Fathers
--GROUP BY FatherId
;WITH FatherAndEldest AS (
SELECT Seq = ROW_NUMBER() OVER (PARTITION BY FatherId ORDER BY age DESC), FatherId, age
FROM @Fathers
) SELECT FatherId, age FROM FatherAndEldest WHERE Seq = 1
How will you learn unless you try?
For fast, accurate and documented assistance in answering your questions, please read this article.
Understanding and using APPLY, (I) and (II) Paul White
Hidden RBAR: Triangular Joins / The "Numbers" or "Tally" Table: What it is and how it replaces a loop Jeff Moden
June 8, 2010 at 4:30 am
Jan Van der Eecken (6/8/2010)
Why make it that complicated?
DECLARE @Fathers TABLE (FatherId VARCHAR(10), age INT)
INSERT INTO @Fathers
SELECT 'Father1', 12
UNION ALL SELECT 'Father1', 17
UNION ALL SELECT 'Father2', 22
UNION ALL SELECT 'Father3', 15
UNION ALL SELECT 'Father3', 17
UNION ALL SELECT 'Father3', 19
SELECT FatherId, MAX ( age ) AS 'age'
FROM @Fathers
GROUP BY FatherId
Or am I missing something?
That was my first answer, until I noticed that for some unspecified reason he didn't want to use GROUP BY. *shrugs*
June 8, 2010 at 4:32 am
DECLARE @Fathers TABLE (FatherId VARCHAR(10), age INT)
INSERT INTO @Fathers
SELECT 'Father1', 12
UNION ALL SELECT 'Father1', 17
UNION ALL SELECT 'Father2', 22
UNION ALL SELECT 'Father3', 15
UNION ALL SELECT 'Father3', 17
UNION ALL SELECT 'Father3', 19
-- GROUP BY disallowed (probably homework)
--SELECT FatherId, MAX ( age ) AS 'age'
--FROM @Fathers
--GROUP BY FatherId
SELECT FatherID,Age FROM @Fathers F where 1 = (Select Count(1) from @fathers F1 where F.FatherID = f1.FatherID and F.age <= F1.age)
Regards,
Mitesh OSwal
+918698619998
June 8, 2010 at 4:34 am
Jan Van der Eecken (6/8/2010)
Why make it that complicated?
SELECT FatherId, MAX ( age ) AS 'age'
FROM @Fathers
GROUP BY FatherId
Or am I missing something?
Jan Van , think u probably missed out one note from the OP
BUT I DONT WANT TO USE A GROUP BY
~Edit : Wrong quotes fixed.
June 8, 2010 at 5:00 am
ColdCoffee (6/8/2010)
and post data in readily consumable format, so that every one will give it a shot..
see as i was saying this, and as there was sample data in readily consumable format, u now have 3 different answers, all producing what you want exactly 🙂 now its your turn to put all the codes over a million rows and judge the optimized one.. happy learning..
June 8, 2010 at 5:43 am
ColdCoffee (6/8/2010)
Jan Van der Eecken (6/8/2010)
Why make it that complicated?
SELECT FatherId, MAX ( age ) AS 'age'
FROM @Fathers
GROUP BY FatherId
Or am I missing something?
Jan Van , think u probably missed out one note from the OP
BUT I DONT WANT TO USE A GROUP BY
~Edit : Wrong quotes fixed.
Yeah, I misread it as "BUT I DO WANT TO USE A GROUP BY"
June 8, 2010 at 7:16 am
Thanks to all who replied this post. My appologies if it looked so trivial....
Actually it was part of a complex proc and for simplfying I used father daughter exapmple.
I was having a resultset in proc which fetches around 5.7 million records and this resultset makes use of MAX and GROUP BY and it was taking 25 secs to get this resultset. So I was just querious if there is another way to write it without GROUP BY since it was taking lot of time. Although you guys surely suggested another WAY, but it still is taking more than 20 secs.
So it again confirms the TSQL basics that you shouldn't bring huge resultsets in procs unless required.
But this proc was written by someone else and I am not so sure about business logic here. So was just wondering if there can be a faster way to pull all records from table(around 5.7 million).
Hope I make thing a bit more clear...
thanks again..
Online Trainer For SQL DBA and Developer @RedBushTechnologies with 18 yrs exp.
June 8, 2010 at 7:23 am
If you have to aggregate your results, and I'm sure you do given the number of rows you're processing, then GROUP BY is almost certainly the fastest way to do it. You might benefit more from posting the whole query, and also the plan. There are a number of factors which could apply the brakes. As an example, there's a query I was working on this morning which takes a few tens of thousands of rows from a 40-million row table, aggregates & sorts, and spits out a screenful of quite heavily processed results, all in less than three seconds.
For fast, accurate and documented assistance in answering your questions, please read this article.
Understanding and using APPLY, (I) and (II) Paul White
Hidden RBAR: Triangular Joins / The "Numbers" or "Tally" Table: What it is and how it replaces a loop Jeff Moden
Viewing 14 posts - 1 through 13 (of 13 total)
You must be logged in to reply to this topic. Login to reply