2017-08-06 119 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