如何使用SQL Server获取max(date)的行记录?

时间:2017-08-06 11:56:02

标签: sql sql-server stored-procedures

我有两个名为TableNumber and TableDetails

的表

TableNumber

ItemID  TableDetailsID   Qty
----------------------------
111     12121             5
111     12121            20 
112     12121            10
123     12121             5

111     22121            25
111     22121            25
123     22121            2

TableDetails

ID       placed   TableDetailsNumber    Date
--------------------------------------------------
12121    London    555                  2017-05-31
22121    Dubai     556                  2017-07-31   <-- Max Date of Item 111

期待输出

ItemID    Placed    TableDetailsNumber    Date         Qty
----------------------------------------------------------
111       Dubai     556                  2017-07-31    50    //(25 + 25) of 22121
112       London    555                  2017-05-31    10
123       Dubai     556                  2017-07-31     2

我尝试做MAX(日期),但是我不能使用分组来引用列Placed,TableDetails

我不知道如何使用相同的TableDetailsNumber对ItemID的数量求和

请告诉我您的答案以解释,谢谢

3 个答案:

答案 0 :(得分:4)

Row_number()是一个排名窗口函数,它将为1中的每个给定列集以及{中的列的顺序指定一个以partition by开头重置的数字{1}}。

如果我们order bypartition by ItemId,那么每个order by Date desc的最新Date行将获得ItemId row_number()。< / p>

我们可以使用子查询common table expressiontop with ties过滤加入和聚合的结果。

使用top with tiesrow_number()

1

common table expressionrow_number()

select top 1 with ties
    tn.ItemId
  , td.Placed 
  , td.TableDetailsNumber
  , td.Date
  , Qty = sum(tn.Qty)
from TableNumber tn
  inner join TableDetails td
    on tn.TableDetailsId = td.Id
group by
    tn.ItemId
  , td.Placed 
  , td.TableDetailsNumber
  , td.Date
order by row_number() over (partition by tn.ItemId order by td.Date desc);

使用cross apply()的另一个选项:

;with cte as (
select 
    tn.ItemId
  , td.Placed 
  , td.TableDetailsNumber
  , td.Date
  , Qty = sum(tn.Qty)
  , rn = row_number() over (partition by tn.ItemId order by td.Date desc)
from TableNumber tn
  inner join TableDetails td
    on tn.TableDetailsId = td.Id
group by
    tn.ItemId
  , td.Placed 
  , td.TableDetailsNumber
  , td.Date
)
select ItemId, Placed, TableDetailsNumber, Date, Qty 
from cte
where rn = 1;

rextester演示:http://rextester.com/QNV39265

每次回复:

select
    i.ItemId
  , x.Placed 
  , x.TableDetailsNumber
  , x.Date
  , x.Qty 
from (select distinct ItemId from TableNumber) i
  cross apply (
    select top 1
        tn.ItemId
      , td.Placed 
      , td.TableDetailsNumber
      , td.Date
      , Qty = sum(tn.Qty)
    from TableNumber tn
      inner join TableDetails td
        on tn.TableDetailsId = td.Id
    where tn.ItemId = i.Itemid
    group by
        tn.ItemId
      , td.Placed 
      , td.TableDetailsNumber
      , td.Date
    order by td.Date desc
    ) x

答案 1 :(得分:0)

这似乎会返回您想要的结果:

select n.itemid, d.placed, d.TableDetailsNumber, d.date, sum(n.qty)
from tablenumber n join
     tabledetails d
     on n.TableDetailsId = d.TableDetailsId
group by n.itemid, d.placed, d.TableDetailsNumber;

但这并没有得到最新的约会。为此:

select nd.*
from (select n.itemid, d.placed, d.TableDetailsNumber, d.date, sum(n.qty),
             max(d.date) over (partition by n.itemid) as maxdate
      from tablenumber n join
           tabledetails d
           on n.TableDetailsId = d.TableDetailsId
      group by n.itemid, d.placed, d.TableDetailsNumber
     ) nd
where date = maxdate;

答案 2 :(得分:0)

您也可以进行内部联接。我包含了所有的表创建代码,以复制测试用例并证明其准确性。

表格创建和插入

CREATE TABLE TableNumber (ItemID INT, TableDetailsID INT, Qty INT)
CREATE TABLE TableDetails (ID INT, placed VARCHAR(25), TableDetailsNumber INT, DetailsDate Date)


INSERT INTO TableNumber 
    values 
     (111,12121,5),
     (111,12121,20),
     (112,12121,10),
     (123,12121,5),
     (111,22121,25),
     (111,22121,25),
     (123,22121,2)

INSERT INTO TableDetails 
    values 
     (12121,'London',555,'2017-05-31'),
     (22121,'Dubai',556,'2017-07-31')

<强>查询

SELECT
     TN.ItemID
    ,TD.Placed
    ,TD.TableDetailsNumber
    ,MaxTable.maxDate
    ,Sum(TN.Qty) 'Qty'
FROM TableNumber TN
JOIN TableDetails TD 
    on TD.ID = TN.TableDetailsID
JOIN (
        SELECT 
         ItemID
        ,max(TD.DetailsDate) maxDate
        FROM TableNumber TN
        JOIN TableDetails TD 
            on TD.ID = TN.TableDetailsID
        GROUP BY 
         ItemID
        ) as MaxTable
    on MaxTable.maxDate = TD.DetailsDate
    and MaxTable.ItemID = TN.ItemID
GROUP BY 
     tn.ItemId
  , td.Placed 
  , td.TableDetailsNumber
  , MaxTable.maxDate