SQL Server查询 - 按顺序查找

时间:2009-10-07 13:27:28

标签: sql-server

假设我有以下示例表

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

如何根据Created列返回每个组的第一个ItemID?我需要一个查询来返回以下内容:

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 个答案:

答案 0 :(得分:1)

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

注意:在没有查询分析器帮助的情况下完成。所以,请善待:)

答案 1 :(得分:1)

不需要内连接。经典PARTITION BY问题。 没有经过测试,但这应该会让你走上正轨。

SELECT RowNumber() OVER(PARTITION BY GroupID ORDER BY Created ASC) AS RowNum, * 
FROM YourTable

答案 2 :(得分:1)

取决于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记录并列,它将返回两者,这可能是有利的,或者根据您的需要而产生的痛苦,可以使用select distinct将其删除为1。

答案 3 :(得分:0)

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