Solved

SQL Max Group By to get the second largest value

Posted on 2015-01-12
8
95 Views
Last Modified: 2015-01-12
Hi there,

I have the below query to obtain the largest value using group by to get the largest size_min value for each model type. However I would like to get the second largest value for size_min using the same premise of which groups by model_type gets the max size_min but obtaining the actual value for price_1 and price_2 like below.

I may have confused you there,  but I have also attached a spreadsheet which better illustrates what I would like to do:

SELECT        tt.model_ID, tt.model_type, tt.size_min, tt.model_price_1, tt.model_price_2
FROM            dbo.Model AS tt INNER JOIN
                             (SELECT        model_type, MAX(size_min) AS MaxMin
                               FROM            dbo.Model E1
                               GROUP BY model_type) AS groupedtt ON tt.model_type = groupedtt.model_type AND tt.size_min = groupedtt.MaxMin;

Open in new window



I  hope this makes sense and thank you for your help in advance.
Table-structure-and-results.xls
0
Comment
Question by:databarracks
  • 6
  • 2
8 Comments
 
LVL 142

Expert Comment

by:Guy Hengel [angelIII / a3]
ID: 40546069
to get the Nth number in an order you can use ROW_NUMBER() function in a subquery, similarly to what I suggest in this article:http://www.experts-exchange.com/Database/Miscellaneous/A_3203-DISTINCT-vs-GROUP-BY-and-why-does-it-not-work-for-my-query.html

select * from (
SELECT        tt.model_ID, tt.model_type, tt.size_min, tt.model_price_1, tt.model_price_2
  , row_number() over (partition by tt.model_ID, tt.model_type  order by  tt.size_min desc ) rn
FROM            dbo.Model AS tt
)
where rn = 2

Open in new window


the issue that I see is that if there is only 1 single record for a "partition", it will not return anything...
in that case, we can add something like this to make sure we still get at least 1 row


select * from (
SELECT        tt.model_ID, tt.model_type, tt.size_min, tt.model_price_1, tt.model_price_2
  , row_number() over (partition by tt.model_ID, tt.model_type  order by  tt.size_min desc ) rn
 , count(*) over ( partition by tt.model_ID, tt.model_type  ) cnt
FROM            dbo.Model AS tt
)
where rn = 2 or cnt = 1

Open in new window

0
 

Author Comment

by:databarracks
ID: 40546072
Hi Guy,

I am getting incorrect syntax here FROM  dbo.Model AS tt)
0
 
LVL 142

Accepted Solution

by:
Guy Hengel [angelIII / a3] earned 500 total points
ID: 40546075
sorry, I forgot the alias for the subquery
select * from (
SELECT        tt.model_ID, tt.model_type, tt.size_min, tt.model_price_1, tt.model_price_2
  , row_number() over (partition by tt.model_ID, tt.model_type  order by  tt.size_min desc ) rn
 , count(*) over ( partition by tt.model_ID, tt.model_type  ) cnt
FROM            dbo.Model AS tt
) sq
where rn = 2 or cnt = 1
                                          

Open in new window

0
 

Author Comment

by:databarracks
ID: 40546077
Hey Guy,

That fixed the error but I am getting all the rows and not 3 rows as per my spreadsheet?
0
Best Practices: Disaster Recovery Testing

Besides backup, any IT division should have a disaster recovery plan. You will find a few tips below relating to the development of such a plan and to what issues one should pay special attention in the course of backup planning.

 

Author Comment

by:databarracks
ID: 40546080
When I run the query all rn and cnt values are 1???
0
 

Author Comment

by:databarracks
ID: 40546082
Ahhhh alas It was because of the id column inside the partition statement. Seeing as they are unique it makes sense. Removed this from the query and it works:)
0
 

Author Comment

by:databarracks
ID: 40546083
Many thanks for your help on this Guy, you have been tremendous
0
 

Author Closing Comment

by:databarracks
ID: 40546084
Excellent, responsive and also added extra information which is helpful. Brilliant stuff
0

Featured Post

PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Complex SQL script 1 31
Benefits of SMB Fileshare 3 63
check the deletion of SQL job on who delete/disable it 12 27
Get Duration of last Status Update 4 29
In this article I will describe the Copy Database Wizard method as one possible migration process and I will add the extra tasks needed for an upgrade when and where is applied so it will cover all.
This article describes how to use the timestamp of existing data in a database to allow Tableau to calculate the prior work day instead of relying on case statements or if statements to calculate the days of the week.
This is used to tweak the memory usage for your computer, it is used for servers more so than workstations but just be careful editing registry settings as it may cause irreversible results. I hold no responsibility for anything you do to the regist…
Internet Business Fax to Email Made Easy - With  eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, f…

911 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now