I have a table with three columns: A,B,C
.
The values are:
+---+-----+----+
| 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 |
+---+-----+----+
If I first order the data by column A
, then column B
, then column C
(although I did make all column C
values the same per column A
value) how would I select the "first row" per column A
?
So, this should result in:
+---+-----+----+
| A | B | C |
+---+-----+----+
| 1 | -10 | 5 |
| 2 | 0 | 12 |
| 3 | -10 | 14 |
| 4 | 0 | 8 |
| 5 | -5 | 6 |
+---+-----+----+
groupby. nth() function is used to get the value corresponding the nth row for each group. To get the first value in a group, pass 0 as an argument to the nth() function.
To return only the first row that matches your SELECT query, you need to add the LIMIT clause to your SELECT statement. The LIMIT clause is used to control the number of rows returned by your query. When you add LIMIT 1 to the SELECT statement, then only one row will be returned.
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
or
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
Create a composite index on (a, b, c)
for the queries to work faster.
Which one is more efficient depends on your data distribution.
If you have few distinct values of a
but lots of records within each a
, the second query would be better.
You could improve it even more by creating an indexed view:
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
SELECT *
FROM
(SELECT *,
ROW_NUMBER() OVER (PARTITION BY Dealld
ORDER BY Price, Dealld) rn
FROM DealOffers) q
WHERE rn = 1
ORDER BY Name
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With