2017-08-02 145 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;