Reputation: 275
I'd like to track my gas mileage ("MPG") from tank to tank.
Here is my Stops
table:
stopID, int(11) auto_increment
vendorID, int(11)
vehicleID, int(11)
mileage, int(11)
date, date
gallons, float
cost, float
remarks, varchar(32)
Here is my Vendors
table:
vendorID, int(11) auto_increment
vendor, varchar(32)
street, varchar(32)
city, varchar(32)
state, varchar(2)
zip, varchar(5)
Here is my Vehicles
table:
vehicleID, int(11) auto_increment
year, year(4)
make, varchar(16)
model, varchar(16)
type, varchar(16)
vin, varchar(32)
So far I'm using the following query (it works), to which I'd like to add a calculated MPG
column:
SELECT v.vendorID,
v.vendor,
v.city,
v.state,
FORMAT(s.mileage , 0 ) Miles ,
DATE_FORMAT(s.date , '%m/%d/%y' ) Date ,
FORMAT(s.gallons , 3 ) Gal ,
FORMAT(s.cost , 2 ) Cost ,
FORMAT(s.cost /s.gallons , 3 ) Rate
FROM Stops s
INNER JOIN Vendors v
ON s.vendorID =v.vendorID
AND s.remarks ='Fuel'
AND s.vehicleID =2
AND s.date >= '2014-07-01'
ORDER BY `Date` DESC
Here is a typical output from the existing query (without MPG column):
vendorID vendor city state Miles Date Gal Cost Rate (MPG)
14 Sunoco Arnold MD 122,104 07/18/14 3.741 15.22 4.068
14 Sunoco Arnold MD 121,936 07/16/14 3.633 14.89 4.099
14 Sunoco Arnold MD 121,770 07/14/14 3.276 13.43 4.100
29 BP Washington DC 121,620 07/11/14 3.635 15.26 4.198
I tried looking for answers already (both Stack Overflow and in the mySQL documentation), but they all seem to depend on having consecutive ID values, or having a particular column sorted in a certain way. Since I have multiple vehicles and multiple stops (not just for remarks
= 'Fuel'), those solutions don't work. Please feel free to ask any questions to clarify, and I'll update my question as needed to provide additional info.
Upvotes: 0
Views: 1750
Reputation: 2576
Following a suggestion I made in the question comments, if you add a self reference column to Stops
the solution would be a lot easier without the need for maintaining any order:
Stops
table would be:
stopID, int(11) auto_increment
vendorID, int(11)
vehicleID, int(11)
mileage, int(11)
date, date
gallons, float
cost, float
remarks, varchar(32)
previous_stopID int(11)
And the query to get MPG
would be:
SELECT cur.stopID, cur.vendorID, (cur.mileage-prev.mileage)/cur.gallons as MPG
FROM Stops cur INNER JOIN Stops prev
WHERE cur.prev_StopID = prev.stopID
You could then join/merge this with Vendors
to get any additional columns you need.
Upvotes: 1
Reputation: 20804
You are going to have to use a self join. This answer will show you the general idea, but it's untested and may have errors.
select (ThisStop.mileage - PreviousStop.mileage) / ThisStop.gallons mpg
from stops.ThisStop join stops.PreviousStop on ThisStop.vehicleId = PreviousStop.vehicleId
where PreviousStop.date =
(select max(date) from stops
where vehicleId = ThisStop.vehicleId
and date < ThisStop.date)
If you want to identify the vendor, get it from PreviousStop.
Upvotes: 0