2017-08-02 142 views
1

我有一個表中的下列信息稱爲TankInfo:SQL條件求和和最大時間

Tank Compartment Product _Date _Time Volume x x1 GAS 2017-08-02 10:42 10000 x x2 GAS 2017-08-02 10:44 20000 x x1 GAS 2017-08-02 13:42 9000 x x2 GAS 2017-08-02 13:39 20000 x x1 GAS 2017-08-02 23:42 9000 x x2 GAS 2017-08-02 23:54 21000 y y1 GAS 2017-08-02 10:42 10000 y y2 DIESEL 2017-08-02 10:43 5000 y y1 GAS 2017-08-02 14:42 10000 y y2 DIESEL 2017-08-02 14:52 5000 y y1 GAS 2017-08-02 23:12 10000 y y2 DIESEL 2017-08-02 23:51 5000

我需要能夠添加廂容積在一起,如果他們是相同的坦克和攜帶相同產品,只彙總最大時間記錄。所以上表將被歸結爲如下所示:

Tank Product _Date _Time Volume x GAS 2017-08-02 23:54 30000 y GAS 2017-08-02 23:12 10000 y DIESEL 2017-08-02 23:51 5000

我想我可以做到以下幾點:

Select 
    z.Tank 
    ,z.Product 
    ,z._Date 
    --,z._Time 
    ,sum(Volume) Volume 
from (
Select 
    ti.Tank 
    ,ti.Compartment 
    ,ti.Product 
    ,ti._Date 
    ,max(ti._Time) _Time 
from TankInfo ti 
Group by 
    ti.Tank 
    ,ti.Compartment 
    ,ti.Product 
    ,ti._Date 
) z 
left join(
Select 
    Tank 
    ,Compartment 
    ,Product 
    ,_Date 
    ,_Time 
    ,Volume 
from TankInfo 
) x 
    on x.Tank = z.Tank 
    and x.Compartment = z.Compartment 
    and x.Product = z.Product 
    and x._Time = z._Time 
Group by 
    z.Tank 
    ,z.Product 
    ,z._Date 

運行此,我得到了下面的表格,和我我堅持如何能夠獲得最大時間。有任何想法嗎?

Tank Product  _Date _Time Volume 
x   GAS  2017-08-02 23:42 9000 
x   GAS  2017-08-02 13:39 21000 
y   GAS  2017-08-02 23:12 10000 
y   DIESEL 2017-08-02 23:51 5000 
+0

第一排體積30000? –

+0

第一行爲30,000,因爲它查看x1和x2的最大時間,並將兩個卷相加。 21000 + 9000並且將這個容器的總結x設爲30000 – ghawes

回答

1

使用CTE你的日期和時間組合成類型datetame的一列只有這樣才能正確彙總,發現最大的時間戳和加入時間戳以獲得正確的卷:

WITH TI (Tank, Compartment, Product, _Date, _Time, TimeStamp, Volume) 
AS (SELECT Tank, Compartment, Product, _Date, _Time, 
    (CAST(_Date AS DATETIME) + CAST(_Time AS DATETIME)) AS TimeStamp, Volume 
    FROM TankInfo) 
SELECT 
    TI.Tank, 
    TI.Product, 
    CAST(MAX(TimeStamp) AS date) AS _Date, 
    CAST(MAX(TimeStamp) AS time) AS _Time, 
    SUM(TI.Volume) AS Volume 
FROM TI 
JOIN (SELECT Tank, Product, MAX(TimeStamp) AS MaxTimeStamp 
     FROM TI GROUP BY Tank, Compartment, Product) AS TIAggregated 
     ON TI.TimeStamp = TIAggregated.MaxTimeStamp 
GROUP BY TI.Tank, TI.Product 
ORDER BY SUM(TI.Volume) DESC 
+0

這正是我正在尋找的,謝謝! – ghawes

0

您只需在您的時間值周圍添加MAX(),例如,

Select 
    z.Tank 
    ,z.Product 
    ,z._Date 
    ,Max(z._Time) _Time 
    ,sum(Volume) Volume 
from (
Select 
    ti.Tank 
    ,ti.Compartment 
    ,ti.Product 
    ,ti._Date 
    ,max(ti._Time) _Time 
from TankInfo ti 
Group by 
    ti.Tank 
    ,ti.Compartment 
    ,ti.Product 
    ,ti._Date 
) z 
left join(
Select 
    Tank 
    ,Compartment 
    ,Product 
    ,_Date 
    ,_Time 
    ,Volume 
from TankInfo 
) x 
    on x.Tank = z.Tank 
    and x.Compartment = z.Compartment 
    and x.Product = z.Product 
    and x._Time = z._Time 
Group by 
    z.Tank 
    ,z.Product 
    ,z._Date 
1
select tp.Tank, tp.Product, max(convert(datetime, latest._Date) + latest._Time), sum(latest.Volume) 
from (select distinct Tank, Product from TankInfo) tp 
cross apply (
    select top 1 * from TankInfo 
    where Tank=tp.Tank and Product=tp.Product 
    order by _Date desc, _Time desc) latest 
group by tp.Tank, tp.Product 
+0

這是一個非常好的解決方案(儘管您應該在子查詢中使用表別名)。 –

1

所以,如果你所有的數據都在同一天發表Laghing維吉爾的答案纔有效。

不幸的是,在我的嘗試中,我想不出任何更清潔的東西,因爲正如你所提到的那樣,日期/時間信息被存儲(並且我假設它將被報告)單獨的列。

,但是這是我能想出:

WITH last_fill AS 
(--Get the last time each tank/product pair was filled. 
SELECT 
    tank, 
    product, 
    _date, 
    _time, 
    RANK() OVER (PARTITION BY tank, product ORDER BY _date DESC, _time DESC) AS highlander 
FROM tankinfo 
), last_fill_volume AS 
(--Get the last time each compartment was filled. 
SELECT 
    tank, 
    compartment, 
    product, 
    _date, 
    _time, 
    RANK() OVER (PARTITION BY tank, compartment, product ORDER BY _date DESC, _time DESC) AS highlander 
FROM tankinfo 
) 
SELECT 
    ti.tank, 
    ti.product, 
    lf._date, 
    lf._time, 
    SUM(ti.volume) AS total_volume 
FROM 
    tankinfo ti 
    INNER JOIN last_fill lf 
     ON 
     (
      ti.tank = lf.tank AND 
      ti.product = lf.product AND 
      lf.highlander = 1 
     ) 
    INNER JOIN last_fill_volume lfv 
     ON 
     (
      ti.tank = lfv.tank AND 
      ti.compartment = lfv.compartment AND 
      ti.product = lfv.product AND 
      ti._date = lfv._date AND 
      ti._time = lfv._time AND 
      lfv.highlander = 1 
     ) 
GROUP BY ti.tank,ti.product,lf._date,lf._time 
1

我會用row_number()做到這一點:

SELECT tank, product, MAX(CAST(_date as datetime) + _time), SUM(Volume) as Volume 
FROM (SELECT ti.*, 
      ROW_NUMBER() OVER (PARTITION BY tank, product ORDER BY _date DESC, _time DESC) as seqnum 
     FROM tankinfo ti 
    ) ti 
WHERE seqnum = 1 
GROUP BY tank, product;