获取该月每个项目的第一个和最后一个记录

时间:2014-04-14 09:36:36

标签: sql sql-server

Product ID     Quantity     DateAdded
1              100          4/1/14
2              200          4/2/14
3              300          4/2/14
1              80           4/3/14
3              40           4/5/14
2              5            4/6/14
1              10           4/7/14

我正在使用此SQL语句显示每个项目的第一个和最后一个记录:

SELECT 
    ProductID, MIN(Quantity) AS Starting, MAX(Quantity) AS Ending 
FROM 
    Records
WHERE 
    DateAdded BETWEEN '2014-04-01' AND '2014-04-30'
GROUP BY 
    ProductID, Quantity

但是我得到的起始列和结束列的值相同。我希望实现这样的目标:

Product ID     Starting     Ending
1              100          10
2              200          5
3              300          40

6 个答案:

答案 0 :(得分:3)

使用row_number()排名功能

select starting.*, ending.ending
from
    (select ProductID, quantity as starting from 
            (select * , ROW_NUMBER() over (partition by productid order by dateadded) rn 
             from yourtable   
             where DateAdded BETWEEN '2014-04-01' AND '2014-04-30'
     ) first 
     where rn = 1) starting
    inner join 
    (select ProductID, quantity as ending from 
            (select * , ROW_NUMBER() over (partition by productid order by dateadded desc) rn 
             from yourtable   
             where DateAdded BETWEEN '2014-04-01' AND '2014-04-30'
    ) last 
    where rn = 1) ending
    on starting.productid=ending.productid

第一个子查询获取该时间段的第一个条目,第二个子查询获取最后一个条目

答案 1 :(得分:2)

您获得的数量相同,因为您在quantity以及产品中汇总group by。您正确编写的查询版本将是:

SELECT ProductID, MIN(Quantity) AS Starting, MAX(Quantity) AS Ending 
FROM Records
WHERE DateAdded BETWEEN '2014-04-01' AND '2014-04-30'
GROUP BY ProductID;

但是,这并没有给出第一个和最后一个值。它只给你最小和最大的。要获取这些值,请使用row_number()和条件聚合:

SELECT ProductID,
       MAX(CASE WHEN seqnum_asc = 1 THEN Quantity END) as Starting,
       MAX(CASE WHEN seqnum_desc = 1 THEN Quantity END) as Ending
FROM (SELECT r.*,
             row_number() over (partition by product order by dateadded asc) as seqnum_asc,
             row_number() over (partition by product order by dateadded desc) as seqnum_desc
      FROM Records r
     ) r
WHERE DateAdded BETWEEN '2014-04-01' AND '2014-04-30'
GROUP BY ProductID;

如果您使用的是SQL Server 2012,则还可以将其与FIRST_VALUE()LAST_VALUE()一起使用,而不是row_number()

答案 2 :(得分:0)

将您的查询更改为此

SELECT 
    ProductID, MIN(Quantity) AS Starting, MAX(Quantity) AS Ending 
FROM 
    Records
WHERE 
    DateAdded BETWEEN '2014-04-01' AND '2014-04-30'
GROUP BY 
    ProductID

您无需为数量组成

答案 3 :(得分:0)

DECLARE @test Table 
(ID INT, Name INT)
INSERT INTO @test 
VALUES
(1,  100),
(2, 200),
(3,  300 ),
(1,  5),
(2, 10),
    (3, 15);

    select ID,MIN(name),MAX(name) from @test
    group by ID 

答案 4 :(得分:0)

这适用于2012年及更新版本:

with x as (
select distinct productid
,first_value(quantity) over(partition by productid order by dateadded
    range between unbounded preceding  and current row) as starting
,last_value(quantity) over(partition by productid order by dateadded
    range between current row and unbounded following) as ending
from #t
)
select productid, starting, ending
from x

单人通过表格。

答案 5 :(得分:-1)

我没有在SQL Server上尝试过,但在MySQL上这个SQL正在运行:

SELECT 
    ProductID, MAX(Quantity) AS Starting, MIN(Quantity) AS Ending 
FROM 
    Records
WHERE 
    DateAdded BETWEEN '2014-04-01' AND '2014-04-30'
GROUP BY 
    ProductID;

对于DateAdded字段:

SELECT 
    ProductID, MAX(Quantity) AS Starting, MIN(Quantity) AS Ending 
FROM 
    Records
WHERE 
    convert(datetime, DateAdded) BETWEEN '2014-04-01' AND '2014-04-30'
GROUP BY 
    ProductID;

P.S。缺少sqlfiddle ...... :(