Solved

How do I return a set of unique records based upon the greatest value in a certain field?

Posted on 2012-04-01
19
327 Views
Last Modified: 2012-04-02
I'm using SQL Server Express 2008 and Management Studio...

I have multiple records that are returned on each player; I want to return only the records with the highest value for each player in the field called 'PO'.

*Attached JPEG has a snapshot of sample table data showing what I am currently getting and what I would like to get....

Many thanks...
sql-jpeg.JPG
0
Comment
Question by:jazjef
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 8
  • 7
  • 2
  • +2
19 Comments
 
LVL 17

Expert Comment

by:Anuroopsundd
ID: 37794661
SELECT lastname,firstname,yearID,teamID,POS, Max( PO ),A,E
FROM tablename
GROUP BY lastname
ORDER BY PO ASC
0
 
LVL 39

Expert Comment

by:Pratima Pharande
ID: 37794699
SELECT X.lastname,X.firstname,X.yearID,Y.teamID,Y.POS,X.PO ,Y.A,Y.E
From tablename Y
inner join (
SELECT lastname,firstname,yearID, Max( PO )
FROM tablename
GROUP BY lastname,firstname,yearID ) X on X.lastname = Y.lastname and X.firstname = Y.firstname and X.yearID= Y.yearID
0
 
LVL 10

Expert Comment

by:plummet
ID: 37794720
Hi, you can try this:


select * from 
(SELECT 
	*,
	rank() over (partition by lastname order by PO desc) as rank
FROM your_table) sub
where rank = 1

Open in new window


this should do it, I think!

Regards
John
0
Get Actionable Data from Your Monitoring Solution

Your communication platform is only as good as the relevance of the information you send. Ensure your alerts get to the right people every time with actionable responses. Create escalation rules that ensure everyone follows the process and nothing is left to chance.

 
LVL 120

Expert Comment

by:Rey Obrero (Capricorn1)
ID: 37795678
try this too

select *
from tableName
where PO= (select max([PO]) from tableName As T
      where T.lastname = TableName.lastname and T.firstname =TableName.firstname and T.yearID= TableName.yearID
      and T.TeamID= TableName.TeamID)
0
 
LVL 4

Author Comment

by:jazjef
ID: 37796289
I don't think I've given you all enough information....Here is the actual SQL statement that returns the record seen in the JPEG:


SELECT Master.nameFirst, Master.nameLast, Fielding.yearID, Fielding.teamID, Fielding.POS, Fielding.PO, Fielding.A, Fielding.E
FROM Master INNER JOIN Fielding ON Master.playerID = Fielding.playerID
WHERE((Fielding.yearID)=1985) AND (nameLast = 'Jones') AND (Fielding.teamID)='kca';


Notice how the nameFirst and nameLast come from a different table than the Fielding table where I get the PO value that must be assessed.....
0
 
LVL 10

Expert Comment

by:plummet
ID: 37796329
How about this?

select * from 
	(SELECT 
	*,
	rank() over (partition by nameLast, nameFirst order by PO desc) as rank
	from
		(SELECT 
		Master.nameFirst, 
		Master.nameLast, 
		Fielding.yearID, 
		Fielding.teamID, 
		Fielding.POS, 
		Fielding.PO, 
		Fielding.A, 
		Fielding.E
		FROM Master INNER JOIN Fielding ON Master.playerID = Fielding.playerID
		) sub1
	) sub2
where rank = 1

Open in new window

0
 
LVL 4

Author Comment

by:jazjef
ID: 37797842
plummet:  It works..... you nailed it.....sort of...
The 'rank' thing seems to leave out some cases. I need to return the highest value of PO for each player comparing all their records and PO values. This 'rank' function seems to leave out some records and only returns about the top 8 records from about 22 possible that should be listed.
0
 
LVL 4

Author Comment

by:jazjef
ID: 37798025
This code doesn't return the record of Jones that has his highest PO value:

select * from
      (SELECT
      *,
      rank() over (partition by nameLast, nameFirst order by PO desc) as rank
      from
            (SELECT
            Master.nameFirst,
            Master.nameLast,
            Fielding.yearID,
            Fielding.teamID,
            Fielding.POS,
            Fielding.PO,
            Fielding.A,
            Fielding.E
            FROM Master INNER JOIN Fielding ON Master.playerID = Fielding.playerID
            ) sub1
      ) sub2
where (yearID)=1985 AND (nameLast = 'Jones') AND (teamID)='kca' AND rank = 1


I need the statement to look at all PO values for each player, find the highest one, then return only that record for each player. The result should be one record for each player on the team----and that record will be the one with the highest PO value for each.
0
 
LVL 120

Expert Comment

by:Rey Obrero (Capricorn1)
ID: 37798208
try this query


SELECT A.*
FROM
(SELECT master.nameFirst, master.nameLast, Fielding.yearID, Fielding.teamID, Fielding.POS, Fielding.PO, Fielding.A, Fielding.E
FROM master INNER JOIN Fielding ON master.PlayerID = Fielding.PlayerID)
As A
Inner Join
(SELECT Max(Fielding.PO) AS MaxOfPO, Fielding.PlayerID, Fielding.yearID, Fielding.teamID
FROM Fielding
GROUP BY Fielding.PlayerID, Fielding.yearID, Fielding.teamID) As B
On A.[PO]=B.MaxOfPO
0
 
LVL 4

Author Comment

by:jazjef
ID: 37798856
capricorn:

You statement omits the following from my earlier post of the SQL statement I have thus far....

where (yearID)=1985 AND (nameLast = 'Jones') AND (teamID)='kca'

Your statement works; but I get every single player from ~1850 to 2011... I can't specify a specific, year, player, and team from any point in your code.

See the JPEG attached to my question.
0
 
LVL 120

Expert Comment

by:Rey Obrero (Capricorn1)
ID: 37798900
try this

SELECT A.*
FROM (SELECT master.nameFirst, master.nameLast, Fielding.yearID, Fielding.teamID, Fielding.POS, Fielding.PO, Fielding.A, Fielding.E FROM master INNER JOIN Fielding ON master.PlayerID=Fielding.PlayerID)  AS A INNER JOIN (SELECT Max(Fielding.PO) AS MaxOfPO, Fielding.PlayerID, Fielding.yearID, Fielding.teamID FROM Fielding GROUP BY Fielding.PlayerID, Fielding.yearID, Fielding.teamID)  AS B ON A.[PO] = B.MaxOfPO
WHERE A.yearID=1985 AND A.nameLast="Jones" AND A.teamID="KCA"
0
 
LVL 4

Author Comment

by:jazjef
ID: 37798907
ATTENTION:

--SAMPLE FILE -- SAMPLE FILE -- SAMPLE FILE -- SAMPLE FILE --

I am attaching an .xls file that has a sample of the current recordset I am able to get, and an explanation of what I actually want. XLS file contains SQL statement as well ....
Get-unique-records-by-PO.xls
0
 
LVL 120

Expert Comment

by:Rey Obrero (Capricorn1)
ID: 37798909
try my last post
0
 
LVL 4

Author Comment

by:jazjef
ID: 37798975
capricorn1:

This code below that you posted returns duplicate player records....13,374 total records to be exact .... It should be about 30 unique records to be the roster of a single major league baseball team.

SELECT A.*
FROM (SELECT master.nameFirst, master.nameLast, Fielding.yearID, Fielding.teamID, Fielding.POS, Fielding.PO, Fielding.A, Fielding.E FROM master INNER JOIN Fielding ON master.PlayerID=Fielding.PlayerID)  AS A INNER JOIN (SELECT Max(Fielding.PO) AS MaxOfPO, Fielding.PlayerID, Fielding.yearID, Fielding.teamID FROM Fielding GROUP BY Fielding.PlayerID, Fielding.yearID, Fielding.teamID)  AS B ON A.[PO] = B.MaxOfPO
WHERE A.yearID=1985 AND A.nameLast="Jones" AND A.teamID="KCA"
0
 
LVL 120

Expert Comment

by:Rey Obrero (Capricorn1)
ID: 37799016
the query should return the unique record. the duplicates could be caused by duplicate records in your table

upload a copy of the db with the two tables..
0
 
LVL 120

Expert Comment

by:Rey Obrero (Capricorn1)
ID: 37799029
try this query, added  And A.PlayerID=B.PlayerID to the join

SELECT A.*
FROM (SELECT master.nameFirst, master.nameLast, Fielding.yearID, Fielding.teamID, Fielding.POS, Fielding.PO, Fielding.A, Fielding.E FROM master INNER JOIN Fielding ON master.PlayerID=Fielding.PlayerID)  AS A INNER JOIN (SELECT Max(Fielding.PO) AS MaxOfPO, Fielding.PlayerID, Fielding.yearID, Fielding.teamID FROM Fielding GROUP BY Fielding.PlayerID, Fielding.yearID, Fielding.teamID)  AS B ON A.[PO] = B.MaxOfPO And A.PlayerID=B.PlayerID
WHERE A.yearID=1985 AND A.nameLast="Jones" AND A.teamID="KCA"
0
 
LVL 4

Author Comment

by:jazjef
ID: 37799062
Error message:

Invalid column name 'PlayerID'.


Error occurs where statement says "A.PlayerID" in the following line: AS B ON A.[PO] = B.MaxOfPO And A.PlayerID=B.PlayerID
0
 
LVL 120

Accepted Solution

by:
Rey Obrero (Capricorn1) earned 500 total points
ID: 37799158
try this

SELECT A.*
FROM (SELECT master.nameFirst, master.nameLast, Fielding.yearID, Fielding.teamID, Fielding.POS, Fielding.PO, Fielding.A, Fielding.E, Fielding.PlayerID FROM master INNER JOIN Fielding ON master.PlayerID=Fielding.PlayerID)  AS A INNER JOIN (SELECT Max(Fielding.PO) AS MaxOfPO, Fielding.PlayerID, Fielding.yearID, Fielding.teamID FROM Fielding GROUP BY Fielding.PlayerID, Fielding.yearID, Fielding.teamID)  AS B ON A.[PO] = B.MaxOfPO And A.PlayerID=B.PlayerID
WHERE A.yearID=1985 AND A.nameLast="Jones" AND A.teamID="KCA"
0
 
LVL 4

Author Comment

by:jazjef
ID: 37799216
capricorn1:
That did it. You nailed it. There are duplicate records remaining etc but that's really not part of my question. You code does what my question specifies and that's good with me. Thanks for sticking with me on this.....

Here's the code that works [I replaced quote marks with apostrophes for nameLast and teamID within the WHERE clause of capricorn1's original post]

SELECT A.*
FROM (SELECT master.nameFirst, master.nameLast, Fielding.yearID, Fielding.teamID, Fielding.POS, Fielding.PO, Fielding.A, Fielding.E, Fielding.PlayerID FROM master INNER JOIN Fielding ON master.PlayerID=Fielding.PlayerID)  AS A INNER JOIN (SELECT Max(Fielding.PO) AS MaxOfPO, Fielding.PlayerID, Fielding.yearID, Fielding.teamID FROM Fielding GROUP BY Fielding.PlayerID, Fielding.yearID, Fielding.teamID)  AS B ON A.[PO] = B.MaxOfPO And A.PlayerID=B.PlayerID
WHERE A.yearID=1985 AND A.nameLast='Jones' AND A.teamID='KCA'
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

This article describes two methods for creating a combo box that can be used to add new items to the row source -- one for simple lookup tables, and one for a more complex row source where the new item needs data for several fields.
AutoNumbers should increment automatically, without duplicates.  But sometimes something goes wrong, and the next AutoNumber value is a duplicate.  This article shows how to recover from this problem.
Learn how to number pages in an Access report over each group. Activate two pass printing by referencing the pages property: Add code to the Page Footers OnFormat event to capture the pages as there occur for each group. Use the pages property to …
Basics of query design. Shows you how to construct a simple query by adding tables, perform joins, defining output columns, perform sorting, and apply criteria.

691 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