我有一个包含三列的表: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
答案 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