GROUP BY有内部查询?或者如何使用相同的过滤器缩短SQL查询?

时间:2018-01-09 03:48:29

标签: sql sql-server tsql

我有一个小程序用来处理汽车的耗气量,存储在SQL数据库中的消耗列表,主要是Lists表。其中一项计划任务是在一段时间内收集所有数据,并显示该期间开始时剩余的汽油,加油汽油量,汽油消耗量,里程数和最后剩余的汽油量。此外,它们分为三种气体类型。

我工作已经有一段时间了,所以我不记得整个故事,但我最终得到了这样的怪物:

  SELECT (SELECT TOP 1 car_name FROM Cars WHERE car_id = l_carid) as CarName, 
(SELECT TOP 1 l_gas_init FROM Lists WHERE l_fueltype = 0 AND l_date >= @ds AND l_date <= @de) as Was92, 
(SELECT TOP 1 l_gas_init FROM Lists WHERE l_fueltype = 1 AND l_date >= @ds AND l_date <= @de) as Was95, 
(SELECT TOP 1 l_gas_init FROM Lists WHERE l_fueltype = 2 AND l_date >= @ds AND l_date <= @de) as WasDT,

SUM(l_city) as CS, 
SUM(l_track) as TS,   

(SELECT TOP 1 l_gas_fin FROM Lists WHERE l_fueltype = 0 AND l_date >= @ds AND l_date <= @de ORDER BY l_date DESC) as Left92, 
(SELECT TOP 1 l_gas_fin FROM Lists WHERE l_fueltype = 1 AND l_date >= @ds AND l_date <= @de ORDER BY l_date DESC) as Left95, 
(SELECT TOP 1 l_gas_fin FROM Lists WHERE l_fueltype = 2 AND l_date >= @ds AND l_date <= @de ORDER BY l_date DESC) as LeftDT

FROM Lists WHERE l_date >= @ds AND l_date <= @de GROUP BY l_carid;

(我在示例中删除了一半的字段,因为它们基本相同)

我知道它看起来很可怕而且很愚蠢,但我无法想出任何可以缩短它的结构。 我会好的,但它没有工作,因为内部队列在GROUP BY开始之前执行,所以除了CS和TS之外,我的所有领域都有第一辆车的结果,那些工作得很好。 / p>

所以我想知道: 如何让这样的东西缩短?也许有一些方法可以在查询中为每个表字段值创建一个字段? 也许它会更容易将其划分为一堆查询? 有没有办法在字段中使用GROUP BY和内部查询?

1 个答案:

答案 0 :(得分:1)

我很确定你只想要条件聚合。如果我不得不猜测:

 SELECT c.car_name as CarName, 
        MAX(CASE WHEN seqnum = 1 AND l.l_fueltype = 1 THEN l_gas_init END) as Was92, 
        MAX(CASE WHEN seqnum = 1 AND l.l_fueltype = 2 THEN l_gas_init END) as Was95, 
        MAX(CASE WHEN seqnum = 1 AND l.l_fueltype = 3 THEN l_gas_init END) as WasDT,
        SUM(l.l_city) as CS, 
        SUM(l.l_track) as TS, 
        MAX(CASE WHEN seqnum = 1 AND l.l_fueltype = 1 THEN l_gas_fin END) as Left92, 
        MAX(CASE WHEN seqnum = 1 AND l.l_fueltype = 2 THEN l_gas_fin END) as Left95, 
        MAX(CASE WHEN seqnum = 1 AND l.l_fueltype = 3 THEN l_gas_fin END) as LeftDT
FROM (SELECT l.*,
             ROW_NUMBER() OVER (PARTITION BY l_fueltype ORDER BY l_date DESC) as seqnum
      FROM Lists l
     ) l JOIN
     Cars c
     ON c.car_id = l.l_carid
WHERE l.l_date >= @ds AND l.l_date <= @de
GROUP BY c.car_name;