在我的一个应用程序中,我需要计算燃料消耗,考虑到完全的加油和部分加油。我的Android应用程序基于SQLite语法和功能。
我尝试在SQL中解决这个难题,并且不希望通过所有行来以编程方式执行此操作。
FULL ='N'的行应该在结果列表中省略,但是它们的值应该添加到下一个FULL ='Y'行。至少这是我的想法。
这是DML(仅显示所需的列):
CREATE TABLE FUELINGS (
ID INTEGER PRIMARY KEY,
MILEAGE INTEGER,
VOLUME DECIMAL(8, 2),
FULL CHAR(1));
以下是此表的一些输入:
INSERT INTO FUELINGS VALUES(1,22995,29.48,'Y');
INSERT INTO FUELINGS VALUES(2,23385,31.27,'Y');
INSERT INTO FUELINGS VALUES(3,23869,16.71,'N');
INSERT INTO FUELINGS VALUES(4,24065,33.18,'Y');
INSERT INTO FUELINGS VALUES(5,24485,30.59,'Y');
INSERT INTO FUELINGS VALUES(6,24956,33.78,'Y');
好的,这就是问题所在。这是我使用的查询:
SELECT T2.MILEAGE,
T2.VOLUME,
T2.FULL,
T2.PREVMILEAGE,
T2.PREVVOLUME,
T2.PREVFULL,
100 * T2.VOLUME / ( T2.MILEAGE - T2.PREVMILEAGE )
FROM (SELECT T.MILEAGE,
T.VOLUME,
T.FULL,
T.PREVMILEAGE,
(SELECT VOLUME
FROM FUELINGS
WHERE MILEAGE = T.PREVMILEAGE
AND MILEAGE IS NOT NULL
AND MILEAGE > 0
AND VOLUME IS NOT NULL
AND VOLUME > 0) AS PREVVOLUME,
(SELECT FULL
FROM FUELINGS
WHERE MILEAGE = T.PREVMILEAGE
AND MILEAGE IS NOT NULL
AND MILEAGE > 0
AND VOLUME IS NOT NULL
AND VOLUME > 0) AS PREVFULL
FROM (SELECT F.MILEAGE,
F.VOLUME,
F.FULL,
(SELECT Max(MILEAGE)
FROM FUELINGS PREV
WHERE PREV.MILEAGE < F.MILEAGE
AND MILEAGE IS NOT NULL
AND MILEAGE > 0
AND VOLUME IS NOT NULL
AND VOLUME > 0) AS PREVMILEAGE
FROM FUELINGS F
WHERE MILEAGE IS NOT NULL
AND MILEAGE > 0
AND VOLUME IS NOT NULL
AND VOLUME > 0) AS T
WHERE PREVMILEAGE IS NOT NULL) AS T2
ORDER BY T2.MILEAGE;
结果如下:
T2.MILEAGE T2.VOLUME T2.FULL T2.PREVMILEAGE T2.PREVVOLUME T2.PREVFULL 100 * T2.VOLUME / (T2.MILEAGE - T2.PREVMILEAGE)
23385 31.27 Y 22995 29.48 Y 8.017948717948718
23869 16.71 N 23385 31.27 Y 3.4524793388429753
24065 33.18 Y 23869 16.71 N 16.928571428571427
24485 30.59 Y 24065 33.18 Y 7.283333333333333
24956 33.78 Y 24485 30.59 Y 7.171974522292993
16.92是错误的,因为在那之前加油是部分加油。我需要求和并计算两行。我知道可能有一个以上的部分加油。但我没有任何线索如何构建FULL ='N'值的范围,将它们相加并将它们添加到下面的FULL ='Y'值。
可以请有人把我放在正确的方向。我怎样才能做到这一点?
非常感谢提前。
修改/溶液
SELECT T.MILEAGE,
T.PREVMILEAGE,
SUM(VOLUME),
100 * SUM(VOLUME) / ( T.MILEAGE - T.PREVMILEAGE )
FROM (SELECT F1.MILEAGE AS MILEAGE,
MAX(F2.MILEAGE) AS PREVMILEAGE
FROM FUELINGS F1
LEFT OUTER JOIN FUELINGS F2
ON F1.MILEAGE > F2.MILEAGE
AND F2.FULL = 'Y'
AND F2.MILEAGE IS NOT NULL
AND F2.MILEAGE > 0
AND F2.VOLUME IS NOT NULL
AND F2.VOLUME > 0.0
WHERE F1.FULL = 'Y'
AND F1.MILEAGE IS NOT NULL
AND F1.MILEAGE > 0
AND F1.VOLUME IS NOT NULL
AND F1.VOLUME > 0.0
GROUP BY F1.MILEAGE) AS T,
(SELECT VOLUME
FROM FUELINGS F3
WHERE F3.MILEAGE > T.PREVMILEAGE
AND F3.MILEAGE <= T.MILEAGE)
GROUP BY T.MILEAGE
答案 0 :(得分:0)
如果您有一个名为FuelingsFull的表,您的原始查询将起作用,该表仅包含有关完全加油的完整信息。这可以从Fueling中总结出来。使用窗口函数的过程会更简单,但是你没有SQLite中的那些。
所以,这里有一个关于如何做到这一点的想法。首先,获取之前的完整ID:
select f1.id, max(f2.full) as prevFullId
from fuelings f1 left outer join
fuelings f2
on f1.id > f2.id and
f2.full = 0
group by f1.id
现在,你有一组所有属于一起的燃料。下一个查询将这个加入到燃料中,然后将它们组合在一起。
select fills.id, max(mileage) as mileage, sum(volume) as volume, count(*) as numFills
from fuelings f join
(select f1.id, max(f2.full) as prevFullId
from fuelings f1 left outer join
fuelings f2
on f1.id > f2.id and
f2.full = 1
group by f1.id
) fills
on f.id > fills.prevFullId and f.id <= fills.id
group by fills.id
将此作为您的FuelingFull,原始查询应该有效。