SQL条件求和和最大时间

时间:2017-08-02 22:24:18

标签: sql sql-server

我在名为TankInfo的表格中有以下信息:

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

5 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

所以Laghing Vergil发布的答案只有在您的所有数据都在同一天时才会有效。

可悲的是,在我的尝试中,我想不出任何更干净的东西,因为正如你所提到的那样,日期/时间信息被存储(我认为是在报告中)单独的列。

但这是我能够提出的:

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

答案 2 :(得分: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

答案 3 :(得分: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;

答案 4 :(得分: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