选择每组的第一行

时间:2012-06-07 10:52:36

标签: sql sql-server sql-server-2008

我有一个包含三列的表:A,B,C

值为:

+---+-----+----+
| A |  B  | C  |
+---+-----+----+
| 1 | -10 |  5 |
| 1 |   0 |  5 |
| 1 |  10 |  5 |
| 2 |  10 | 12 |
| 2 |   0 | 12 |
| 3 | -10 | 14 |
| 4 |   0 |  8 |
| 4 |  10 |  8 |
| 5 |   0 |  6 |
| 5 |   1 |  6 |
| 5 |  -5 |  6 |
+---+-----+----+

如果我首先按列A排序数据,然后按列B排序,则列C(尽管我确实使每列C列的值相同{ {1}}值)我如何选择"第一行"每列A

所以,这应该导致:

A

3 个答案:

答案 0 :(得分:16)

SELECT  a, b, c
FROM    (
        SELECT  *, ROW_NUMBER() OVER (PARTITION BY a ORDER BY b, c) rn
        FROM    mytable
        ) q
WHERE   rn = 1
ORDER BY
        a

SELECT  mi.*
FROM    (
        SELECT  DISTINCT  a
        FROM    mytable
        ) md
CROSS APPLY
        (
        SELECT  TOP 1 *
        FROM    mytable mi
        WHERE   mi.a = md.a
        ORDER BY
                b, c
        ) mi
ORDER BY
        a

(a, b, c)上创建一个综合索引,以使查询更快地运行。

哪一个更有效取决于您的数据分布。

如果a的值不同,但每个a内有大量记录,则第二个查询会更好。

您可以通过创建索引视图来进一步改进它:

CREATE VIEW v_mytable_da
WITH   SCHEMABINDING
AS
       SELECT  a, COUNT_BIG(*) cnt
       FROM    dbo.mytable
       GROUP BY
               a

GO

CREATE UNIQUE CLUSTERED INDEX
       pk_vmytableda_a
ON     v_mytable_da (a)

GO

SELECT  mi.*
FROM    v_mytable_da md
CROSS APPLY
        (
        SELECT  TOP 1 *
        FROM    mytable mi
        WHERE   mi.a = md.a
        ORDER BY
                b, c
        ) mi
ORDER BY
        a

答案 1 :(得分:1)

这是一个经典问题,之前有人问过

How do I select the first row per group in an SQL Query?

Select first row in each GROUP BY group?

一个好的搜索短语是“选择组sql server的第一行”

答案 2 :(得分:0)

SELECT *
FROM
  (SELECT *,
          ROW_NUMBER() OVER (PARTITION BY Dealld
                             ORDER BY Price, Dealld) rn
   FROM DealOffers) q
WHERE rn = 1
ORDER BY Name