(no subject)

Jun 28, 2009 00:59

Добрый вечер!

Мне встретилась задачка, связанная с sql (субд - MS SQL Server 2005). Врядли можно назвать ее нестандартной. Но, во всяком случае, у меня не получилось ее решить стандартными средствами SQL Server.

Задача:
есть таблица, которая содержит группы строк. Строки группируются по одинаковому значению одного из столбцов (назовем его col1). Нужно выбрать из каждой группы строку, имеющую минимальное значение столбца col2.

При этом значения в колонке col2 могут дублироваться. Если col2 содержит несколько минимальных значений для одной группы - все равно должна быть выбрана только одна строка.

у меня получилось следующее решение:


вот таблица:

CREATE TABLE [a](
[id] [INT] IDENTITY(1,1) NOT NULL,
[col1] [INT] NULL,
[col2] [INT] NULL,
[STR] [VARCHAR](50) NULL,
[rn] [INT] NULL,
CONSTRAINT [PK_a] PRIMARY KEY CLUSTERED ([id] ASC)
WITH (IGNORE_DUP_KEY = OFF))

В таблицу добавлено дополнительное поле rn. Это уникальный номер строки, который расставлен так, что нужная строка в группе имеет минимальный номер.
Вот заполнение этого поля:

UPDATE a
SET a.rn = a2.rn
FROM
(SELECT row_number() OVER (ORDER BY col1 DESC, col2 ASC) rn, id FROM a) a2
WHERE a.id = a2.id

Собственно, вот запрос, который выбирает данные:

SELECT * FROM a
WHERE rn in (
SELECT MIN(rn)
FROM a
GROUP BY col1)

Вроде получились не очень большие запросы. Можно, конечно, написать один общий запрос без использования дополнительного поля, но так а) короче, б) в моем случае это все будет использоваться в хранимой процедуре с временными таблицами, так что этот вариант даже удобнее одного большого запроса.

В оракле можно выбрать первую строку из каждой группы вот так:

FIRST_VALUE(column) over (PARTITION BY GROUP_ID)

Может быть, кто-нибудь знает короткий и красивый способ решения этой задачи для SQL Server 2005?

Previous post Next post
Up