用于处理与聚合的关系的逻辑

时间:2013-09-23 18:44:10

标签: sql sql-server

我有这个数据集:

|  ID | TYPE | PERCENT |
------|------|---------|
| 123 |    A |     0.5 |
| 123 |    B |     0.5 |
| 456 |    A |     0.7 |
| 456 |    B |     0.3 |
| 789 |    A |       1 |

我想要以下结果:

|  ID | TYPE | PERCENT |
------|------|---------|
| 123 |    A |     0.5 |
| 456 |    A |     0.7 |
| 789 |    A |       1 |

即,为每个MAX(percent)和相应的id获取type

我正在使用

SELECT ... 
FROM
  (SELECT [id], MAX([percent]) AS [p]
  FROM [highest]
  GROUP BY [id]) a
LEFT JOIN [highest] b 
  ON b.[id] = a.[id]
    AND b.[percent] = a.[p]

获得

|  ID |   P | TYPE | PERCENT |
--- --|-----|------|---------|
| 123 | 0.5 |    A |     0.5 |
| 123 | 0.5 |    B |     0.5 |
| 456 | 0.7 |    A |     0.7 |
| 789 |   1 |    A |       1 |

2 个答案:

答案 0 :(得分:3)

尝试此查询:

SELECT  src.[id], src.[type], src.[percent]
FROM (
    SELECT  [id], [type], [percent], 
            ROW_NUMBER() OVER(PARTITION BY h.[id] ORDER BY [percent] DESC, h.[type] ASC) AS RowNum
    FROM    [highest] h
) src
WHERE src.RowNum = 1

答案 1 :(得分:1)

皮肤猫的另一种方法:

SELECT d.ID, m.type, m.[percent]
FROM highest AS d
CROSS APPLY (
  SELECT TOP 1 type, [percent]
  FROM highest
  WHERE ID = d.ID
  ORDER BY [percent] DESC, type ASC
) AS m
GROUP BY d.ID, m.type, m.[percent]
;

也就是说,对于每个不同的ID,都会获取具有最大值(TOP 1 ... ORDER BY [percent] DESCpercent的行。当多个类型具有相同ID的最大值时,将选择在其他类型(type ASC)之前排序的类型。

稍微冗长的等价物(使用DISTINCT而不是GROUP BY):

SELECT DISTINCT d.ID, m.type, m.[percent]
FROM highest AS d
CROSS APPLY (
  SELECT TOP 1 type, [percent]
  FROM highest
  WHERE ID = d.ID
  ORDER BY [percent] DESC, type ASC
) AS m
;

使用正确的索引编制,不应该比@Bogdan Sahlean's suggestion差。