Запрос SQL Server - сначала найти в последовательности - PullRequest
0 голосов
/ 07 октября 2009

Допустим, у меня есть следующая таблица примеров

GroupID        ItemID          Created
-----------------------------------------------
A              ABC             5/1/2009 13:02
A              XZY             5/1/2009 13:01
A              LMO             5/1/2009 13:03
A              DEF             5/1/2009 13:00
A              PQR             5/1/2009 13:04
B              WXY             5/1/2009 13:02
B              HIJ             5/1/2009 13:03
B              STU             5/1/2009 13:01

Как я могу вернуть первый ItemID для каждой группы на основе столбца Created? Мне нужен запрос, чтобы вернуть следующее:

GroupID        ItemID          Created
-----------------------------------------------
A              DEF             5/1/2009 13:00
B              STU             5/1/2009 13:01

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

Редактировать: Пока у меня есть следующее:

select t2.ItemID, count(*) from 
    (select GroupID, min(created) as created from table) t1
        inner join table t2 on t1.created = t2.created
group by t2.itemid

Есть причина, по которой это не сработает? Это медленнее, чем хотелось бы, но обновляет сводную таблицу, так что это не такая уж большая проблема.

Ответы [ 4 ]

1 голос
/ 07 октября 2009

Зависит от версии SQL Server, но начиная с 2005 года имеются функции ранжирования, которые могут упростить его

Select GroupID, ItemID, Created
FROM
(
    select GroupID, ItemID, Created, DENSE_RANK ( ) OVER ( partition by GroupID 
    order by Created asc) as Rank
    from yourTable
) as A
where Rank = 1

Одно замечание: если связать 2 записи, будет возвращено и то и другое, это может быть выгодно, или боль, в зависимости от того, что вам нужно, может быть сброшена до одной с помощью команды «Выбрать отличное».

1 голос
/ 07 октября 2009

Нет необходимости в внутренних соединениях. Классический раздел по проблеме. Не проверено, но это должно поставить вас на правильный путь.

SELECT RowNumber() OVER(PARTITION BY GroupID ORDER BY Created ASC) AS RowNum, * 
FROM YourTable
1 голос
/ 07 октября 2009
SELECT myTable.* 
FROM myTable 
INNER JOIN (
SELECT GroupID, Min(Created) AS MinCreated
FROM myTable) AS SummarizedTable
ON myTable.GroupID = SummarizedTable.GroupID
WHERE myTable.Created = SummarizedTable.MinCreated

Примечание: сделано без помощи анализатора запросов. Так что будьте добры :))

0 голосов
/ 07 октября 2009
select m1.Groupid, m1.itemid, m1.created 
from mytable m1
join 
(select groupid,min(created) as created from mytable) m2
    on m1.groupid = m2.group_id  and m1.created = m2.created
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...