从查询中获得最佳得分结果

时间:2013-08-21 13:19:01

标签: sql-server tsql sql-server-2005

我有一张得分结果的表格。一些结果具有相同的分数。我想通过TrackingNumber对所有结果进行分组,并选择得分最低的记录。如果组内存在平局(组中的最低分数出现不止一次),我不想选择它。这是帮助解释的tsql:

CREATE TABLE Dupe
(
    Id      INT NOT NULL IDENTITY( 1, 1 ) PRIMARY KEY,
    TrackingNumber  INT NOT NULL,
    Name    VARCHAR(50),
    Score   INT NOT NULL
)
GO

INSERT  INTO dbo.Dupe ( TrackingNumber, Name, Score )VALUES ( 1, 'Name1', 1 )
INSERT  INTO dbo.Dupe ( TrackingNumber, Name, Score )VALUES ( 1, 'Name1', 3 )
INSERT  INTO dbo.Dupe ( TrackingNumber, Name, Score )VALUES ( 1, 'Name1', 3 )
INSERT  INTO dbo.Dupe ( TrackingNumber, Name, Score )VALUES ( 1, 'Name1', 5 )
INSERT  INTO dbo.Dupe ( TrackingNumber, Name, Score )VALUES ( 2, 'Name2', 1 )
INSERT  INTO dbo.Dupe ( TrackingNumber, Name, Score )VALUES ( 2, 'Name2', 4 )
INSERT  INTO dbo.Dupe ( TrackingNumber, Name, Score )VALUES ( 2, 'Name2', 9 )
INSERT  INTO dbo.Dupe ( TrackingNumber, Name, Score )VALUES ( 4, 'Name4', 11 )
INSERT  INTO dbo.Dupe ( TrackingNumber, Name, Score )VALUES ( 4, 'Name4', -55 )
INSERT  INTO dbo.Dupe ( TrackingNumber, Name, Score )VALUES ( 4, 'Name4', -55 )

期望的输出:

| ID | TRACKINGNUMBER |  NAME | SCORE |
---------------------------------------
|  1 |              1 | Name1 |     1 |
|  4 |              2 | Name2 |     1 |

有人能指出我如何做到这一点的正确方向吗?

1 个答案:

答案 0 :(得分:1)

我的查询有点复杂,但它可以完成工作:

;WITH tmp (tn, sc) AS
(
    SELECT TrackingNumber, score
    FROM dupe
    GROUP BY TrackingNumber, score
    HAVING COUNT(*) = 1
)
SELECT dupe.*
FROM dupe
INNER JOIN (
    SELECT tn , MIN(sc) AS s
    FROM tmp
    GROUP BY tn
) t2 ON tn = trackingnumber AND s = score

CTE tmp过滤掉所有单个分数的记录(因为不接受多个分数)。然后再次对此表进行分组以找到最小单个分数,然后再次使用实际的sorce表dupe连接以输出所有列。

http://sqlfiddle.com/#!6/eadec/5

您也可以在没有CTE的情况下编写它(仅使用派生表):

SELECT dupe.* FROM dupe
INNER JOIN 
( SELECT tn,min(sc) s FROM 
   ( SELECT TrackingNumber tn, score sc FROM dupe 
     GROUP BY TrackingNumber, score HAVING COUNT(*)=1
   ) tmp GROUP BY tn
) t2 
ON tn=trackingnumber AND s=score

http://sqlfiddle.com/#!6/eadec/6

输出:

| ID | TRACKINGNUMBER |  NAME | SCORE |
---------------------------------------
|  1 |              1 | Name1 |     1 |
|  4 |              2 | Name2 |     1 |
|  7 |              4 | Name4 |    11 |

好的,如果您希望完全忽略具有双倍最小值的跟踪数,请执行以下操作:

SELECT dupe.* FROM dupe INNER JOIN 
(SELECT tn, s FROM dupe INNER JOIN
  (SELECT trackingnumber tn,min(score) s FROM dupe 
   GROUP BY trackingnumber) t1
 ON trackingnumber=tn AND score=s
 GROUP BY tn,s HAVING COUNT(*)=1
) t2 ON trackingnumber=tn AND score=s

得到这个

| ID | TRACKINGNUMBER |  NAME | SCORE |
---------------------------------------
|  1 |              1 | Name1 |     1 |
|  4 |              2 | Name2 |     1 |

http://sqlfiddle.com/#!6/eadec/11