2017-08-06 116 views
2

我有两个表名为TableNumber and TableDetails如何使用SQL Server获取max(date)的行记录?

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除了我不如何使之项ID的数量与同TableDetailsNumber

请给我解释一下答案,了解,感谢

回答

4

Row_number()是排名窗函数,将分配一个号码时将复位开始1partition by每个给定组的列,并且在各列中的order by的顺序。

如果我们partition by ItemIdorder by Date desc然后用最新Date每个ItemId该行给出的1row_number()

由此,我们可以使用子查询common table expressiontop with ties过滤连接和聚合的结果。

使用top with tiesrow_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); 

row_number()

;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; 

一个common table expression另一种选择使用cross apply()

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 

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

每次返回:

+--------+--------+--------------------+------------+-----+ 
| ItemId | Placed | TableDetailsNumber | Date | Qty | 
+--------+--------+--------------------+------------+-----+ 
| 111 | Dubai |    556 | 2017-07-31 | 50 | 
| 112 | London |    555 | 2017-05-31 | 10 | 
| 123 | Dubai |    556 | 2017-07-31 | 2 | 
+--------+--------+--------------------+------------+-----+ 
+0

哪一个将是明智的表现最好的一个? –

+0

@mohamedfaiz它取决于服务器以及您正在处理的行数。 – SqlZim

+0

感谢兄弟。它真的帮助我很多了解 –

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; 
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