SQL Server SELECT only the top unique results

5gfr0r5j  于 2023-10-15  发布在  其他
关注(0)|答案(1)|浏览(109)

I need to grab only 1 value for each unique componentID (so the top 2 rows result from the image would be the perfect result).

SELECT cs.ID ,AvgStatisticData ,cs.ComponentID 
FROM PortEvidence pe
JOIN ComponentStatus cs ON cs.ID=pe.ComponentStatusID
JOIN Component c ON c.ComponentID= cs.ComponentID
WHERE c.ComponentType = 48 
ORDER BY cs.ID DESC

eoigrqb6

eoigrqb61#

All untested but the basic concepts are there...

Modern approach to least:

  • to use cross apply/lateral depending on RDBMS
  • use row_number (window function)
  • use coorlated sub query
  • use sub query and inner join (ANSI -92 assuming you avoid the CTE)

In each of the below I use a common table expression (CTE) just so I don't have to deal with repeating the query or thinking through what elemnts would be needed...

USing a window function:

SELECT ID, AvgStatisticData, component ID
FROM (
  SELECT cs.ID ,AvgStatisticData ,cs.ComponentID
     , row_Number() over (partition by CS.componentID, order by CS.ID Desc) RN 
  FROM PortEvidence pe
  JOIN ComponentStatus cs ON cs.ID=pe.ComponentStatusID
  JOIN Component c ON c.ComponentID= cs.ComponentID
  WHERE c.ComponentType = 48) sub
WHERE RN = 1
ORDER BY cs.ID DESC

Using subquery inner join

With CTE AS(
SELECT cs.ID ,AvgStatisticData ,cs.ComponentID 
FROM PortEvidence pe
JOIN ComponentStatus cs ON cs.ID=pe.ComponentStatusID
JOIN Component c ON c.ComponentID= cs.ComponentID
WHERE c.ComponentType = 48)
SELECT A.** 
FROM CTE A
INNER JOIN (SELECT max(ID) maxID, componentID FROM CTE Group by ComponentID)
 on A.ID = B.MAXID
and A.ComponentID = B.ComponentID
ORDER BY cs.ID DESC

Or using more modern approach assuming SQL Server using table value functions and cross apply

WITH CTE AS (SELECT cs.ID ,AvgStatisticData ,cs.ComponentID 
FROM PortEvidence pe
JOIN ComponentStatus cs ON cs.ID=pe.ComponentStatusID
JOIN Component c ON c.ComponentID= cs.ComponentID
WHERE c.ComponentType = 48)

SELECT B.* 
FROM CTE A
CROSS APPLY (SELECT TOP 1 * 
             FROM CTE B
             WHERE A.ID = B.ID
               and A.ComponentID = B.ComponentID 
             ORDER BY ID Desc) B

ORDER BY cID DESC

OR use a coorlated subquery and exists.

With CTE AS (SELECT cs.ID ,AvgStatisticData ,cs.ComponentID 
FROM PortEvidence pe
JOIN ComponentStatus cs ON cs.ID=pe.ComponentStatusID
JOIN Component c ON c.ComponentID= cs.ComponentID
WHERE c.ComponentType = 48 
ORDER BY cs.ID DESC)
SELECT * 
FROM CTE  A
WHERE EXISTS (
  SELECT max(ID) MAXID, ComponentID
  FROM CTE B
  GROUP BY ComponetID
  HAVING B.MAXID = A.ID
     and B.ComponetID = A.ComponentID)

相关问题