| Author |
Topic |
|
BazzaM
Starting Member
2 Posts |
Posted - 2009-02-12 : 11:35:28
|
| I am trying to limit the results return by a group by clause.Consider this tableRef Pet Pet_Name year_born101 Dog Roxy 2006101 Dog Max 2006101 Cat Ava 2007102 Cat Gremlin 2005103 Dog buddy 2006103 Cat Max 1999I want to return just one entry per ref, and it should be the oldest pet in the house.In the case of 101, it doesn't matter which one is retuned as 2 dogs are the same age.The result should look like this:Ref Pet Pet_Name year_born101 Dog Roxy 2006102 Cat Gremlin 2005103 Cat Max 1999The query I want to run is something like:select ref, pet, pet_name, min(year_born)from my_petsgroup by refThe following query gives me one entry per ref, buttakes min(pet) in this case always "Cat"select ref, min(pet), min(pet_name), min(year_born)from my_petsgroup by refCan I do this without using a sub-query?Thanks for lookingBazza |
|
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2009-02-12 : 12:00:08
|
Here are a few ways - not sure if they satisfy your req of no sub-queries though:declare @t table (Ref int, Pet varchar(10), Pet_Name varchar(15), year_born int)insert @tselect 101, 'Dog', 'Roxy', 2006 union allselect 101, 'Dog', 'Max', 2006 union allselect 101, 'Cat', 'Ava', 2007 union allselect 102, 'Cat', 'Gremlin', 2005 union allselect 103, 'Dog', 'buddy', 2006 union allselect 103, 'Cat', 'Max', 1999--using Row_Number()select ref ,pet ,pet_name ,year_bornfrom ( select ref ,pet ,pet_name ,year_born ,row_number() over (partition by ref order by year_born, pet_name desc) rn from @t ) dwhere rn = 1--using CROSS APPLYselect distinct t.ref ,ca.pet ,ca.pet_name ,ca.year_bornfrom @t tcross apply ( select top 1 pet ,pet_name ,year_born from @t where ref = t.ref order by year_born ) ca--using cancatenationselect ref ,substring(concat,4+1, 20) pet ,substring(concat,4+20+1, 20) pet_name ,convert(int, left(concat,4)) year_bornfrom ( select t.ref ,min(str(year_born, 4) + convert(char(20), pet) + convert(char(20), pet_name)) concat from @t t group by t.ref ) dEDIT (added output):ref pet pet_name year_born----------- ---------- --------------- -----------101 Dog Roxy 2006102 Cat Gremlin 2005103 Cat Max 1999(3 row(s) affected)ref pet pet_name year_born----------- ---------- --------------- -----------101 Dog Max 2006102 Cat Gremlin 2005103 Cat Max 1999(3 row(s) affected)ref pet pet_name year_born----------- -------------------- -------------------- -----------101 Dog Max 2006102 Cat Gremlin 2005103 Cat Max 1999 Be One with the OptimizerTG |
 |
|
|
sodeep
Master Smack Fu Yak Hacker
7174 Posts |
Posted - 2009-02-12 : 12:02:24
|
It will work for this scenerio but maynot work for other case:Select ref, max(pet), max(pet_name), min(year_born)from my_petsgroup by ref |
 |
|
|
sodeep
Master Smack Fu Yak Hacker
7174 Posts |
Posted - 2009-02-12 : 12:05:08
|
quote: Originally posted by TG Here are a few ways - not sure if they satisfy your req of no sub-queries though:declare @t table (Ref int, Pet varchar(10), Pet_Name varchar(15), year_born int)insert @tselect 101, 'Dog', 'Roxy', 2006 union allselect 101, 'Dog', 'Max', 2006 union allselect 101, 'Cat', 'Ava', 2007 union allselect 102, 'Cat', 'Gremlin', 2005 union allselect 103, 'Dog', 'buddy', 2006 union allselect 103, 'Cat', 'Max', 1999--using Row_Number()select ref ,pet ,pet_name ,year_bornfrom ( select ref ,pet ,pet_name ,year_born ,row_number() over (partition by ref order by year_born, pet_name desc) rn from @t ) dwhere rn = 1--using CROSS APPLYselect distinct t.ref ,ca.pet ,ca.pet_name ,ca.year_bornfrom @t tcross apply ( select top 1 pet ,pet_name ,year_born from @t where ref = t.ref order by year_born,pet_name desc ) ca--using cancatenationselect ref ,substring(concat,4+1, 20) pet ,substring(concat,4+20+1, 20) pet_name ,convert(int, left(concat,4)) year_bornfrom ( select t.ref ,min(str(year_born, 4) + convert(char(20), pet) + convert(char(20), pet_name)) concat from @t t group by t.ref ) dEDIT (added output):ref pet pet_name year_born----------- ---------- --------------- -----------101 Dog Roxy 2006102 Cat Gremlin 2005103 Cat Max 1999(3 row(s) affected)ref pet pet_name year_born----------- ---------- --------------- -----------101 Dog Max 2006102 Cat Gremlin 2005103 Cat Max 1999(3 row(s) affected)ref pet pet_name year_born----------- -------------------- -------------------- -----------101 Dog Max 2006102 Cat Gremlin 2005103 Cat Max 1999 Be One with the OptimizerTG
|
 |
|
|
BazzaM
Starting Member
2 Posts |
Posted - 2009-02-13 : 11:54:33
|
| Thanks for that, worked perfectly! |
 |
|
|
sodeep
Master Smack Fu Yak Hacker
7174 Posts |
Posted - 2009-02-13 : 16:37:18
|
quote: Originally posted by BazzaM Thanks for that, worked perfectly!
Cool . |
 |
|
|
|
|
|