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
326 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
Enterprise Mobility and BYOD For Dummies

Like “For Dummies” books, you can read this in whatever order you choose and learn about mobility and BYOD; and how to put a competitive mobile infrastructure in place. Developed for SMBs and large enterprises alike, you will find helpful use cases, planning, and implementation.

 
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

Ransomware: The New Cyber Threat & How to Stop It

This infographic explains ransomware, type of malware that blocks access to your files or your systems and holds them hostage until a ransom is paid. It also examines the different types of ransomware and explains what you can do to thwart this sinister online threat.  

Question has a verified solution.

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

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.
In Part II of this series, I will discuss how to identify all open instances of Excel and enumerate the workbooks, spreadsheets, and named ranges within each of those instances.
In Microsoft Access, learn different ways of passing a string value within a string argument. Also learn what a “Type Mis-match” error is about.
With Microsoft Access, learn how to specify relationships between tables and set various options on the relationship. Add the tables: Create the relationship: Decide if you’re going to set referential integrity: Decide if you want cascade upda…

749 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