SQL:唯一部分的最近日期的返回ID

时间:2013-07-02 16:54:20

标签: sql sql-server tsql aggregate-functions

我如何修改以下查询以仅返回每个唯一Part_Number的最新Quote_Date的Quote.Quote?由于Quote是唯一的,我无法仅返回第一条记录。我知道这种情况几乎以同样的方式被多次询问,但是,我无法使用row_number,rank,partition,derived table等来完全正确...我被卡住了。谢谢你的帮助。

    Sample
    Quote     Part_Number     Quote_Date
    1              a              1/1/12
    2              a              1/2/12
    3              a              1/3/12
    4              b              1/2/12
    5              b              1/3/12
    6              c              1/1/12

    Desired Results
    Quote     Part_Number     Quote_Date
    3              a              1/3/12
    5              b              1/3/12
    6              c              1/1/12

    SELECT Quote.Quote, Quote.Part_Number, MAX(RFQ.Quote_Date) AS Most_Recent_Date
    FROM Quote INNER JOIN RFQ ON Quote.RFQ = RFQ.RFQ
    GROUP BY Quote.Part_Number, Quote.Quote
    HAVING (NOT (Quote.Part_Number IS NULL))

3 个答案:

答案 0 :(得分:3)

由于partition...order by quote_date desc子句,此查询会将最大日期编号为“1”。

select Quote, Part_number, Quote_date,
       rank() over (partition by part_number 
                    order by quote_date desc) as date_order
from sample

在这种情况下,rank()函数通常是比row_number()更好的选择。如果碰巧有两行具有相同的最大日期,则rank()会将它们编号为相同。要查看其工作原理insert into your_table values (7, 'a', '2012-01-03'),请使用rank()运行查询。将其更改为row_number()。看到区别?

使用WHERE子句从那个中选择。

select Quote, Part_number, Quote_date
from 
    (select Quote, Part_number, Quote_date,
            rank() over (partition by part_number 
                         order by quote_date desc) as date_order
    from sample) t1
where date_order = 1;

另一种方法是首先推导出一组零件号和与之相关的最大日期。

select Part_Number, max(Quote_Date) as max_quote_date
from sample
group by Part_number;

然后将其连接到原始表格以获取您需要的任何其他列。

select s.Quote, s.Part_Number, s.Quote_Date
from sample s
inner join (select Part_Number, max(Quote_Date) max_quote_date
            from sample
            group by Part_number) t1
        on s.Part_Number = t1.Part_number
       and s.Quote_Date = t1.max_quote_date
order by Part_Number;

答案 1 :(得分:0)

给它一个机会。我不确定你是否需要Part_Number where子句,但是你把它包含在原始SQL中(作为HAVING子句)所以我保留了它。我显然不确切知道你的数据是如何看的,但重要的是其余的子选择。

SELECT a.Quote, a.Part_Number, a.Quote_Date
FROM
    (SELECT ROW_NUMBER() OVER(PARTITION BY q.Part_Number ORDER BY r.Quote_Date DESC) AS RowNum,
    q.Quote, q.Part_Number, r.Quote_Date
    FROM Quote q INNER JOIN RFQ r ON q.RFQ = r.RFQ
    WHERE q.Part_Number IS NOT NULL) a
WHERE a.RowNum = 1;

答案 2 :(得分:0)

CTE使其易于操作且易于阅读。

;with cte as (
    select
        *,
        row_number() over (partition by Part_Number order by Quote_Date desc) rownum
    from
        @quote
)
select Quote, Part_Number, Quote_Date from cte where rownum = 1