Here is the simplified version of my question. There are two tables o开发者_Go百科ne has machines and the second has their info about their state change with date reference(not actualy the date, but the shift index, that's why I have to make another query to get the date itself). I want to get the last state of each machine.
My query is:SELECT * FROM machines
LEFT JOIN (SELECT * FROM statechange, dates WHERE....ORDER BY date DESC LIMIT 0,1) AS state
ON state.mid=machines.mid
But I get only one machine as a result of the query. How can I do it without creating a view?
select m.*,s.`date` from machines as m
inner join (
select mid,`date`
from statechange
order by `date` desc) as s
on m.mid = s.mid
group by m.mid
You get the latest statechange for every machine by doing something like this.
SELECT mid, max(date)
FROM statechange
GROUP BY mid
Then you join on that to get the current state for every machine. (Guessing at column names.)
SELECT m.*, sc.state, sc.date
FROM machines m
INNER JOIN statechange sc
ON ( sc.mid = m.mid )
INNER JOIN (
SELECT mid, MAX(date) date
FROM statechange
GROUP BY mid
) s
ON ( (s.mid = sc.mid) and (s.date = sc.date) );
I think a view for the current state of every machine might be widely useful, though.
Assuming that the primary key of the statechange
table is something on which Max makes sense (like an integer)
Select ...
From Machines As M
Left Join (
Select S1.mid, Max( S1.PrimaryKeyCol ) As PrimaryKeyCol
From statechange As S1
Join dates As D1
On D1.statechangeFK = S1.PrimaryKeyCol
Where D1.date = (
Select Max( D2.date )
From dates As D2
Where D2.statechangeFK = D1.statechangeFK
)
Group By S1.mid
) As LastStateChange
On LastStateChange.mid = M.mid
Left Join statechange As S
On S.PrimaryKeyCol = LastStateChange.PrimaryKeyCol
The last join is in case you want to return columns from the statechange table.
Revision based on additional info
Select ...
From Machines As M
Left Join (
Select S1.mid, Max( S1.PrimaryKeyCol ) As PrimaryKeyCol
From dates As D1
Join statechange As S1
On S1.DatesForeignKeyCol = D1.PrimaryKeyCol
Where D1.date = (
Select Max( D2.date )
From dates As D2
Join statechange As S2
On S2.DatesForeignKeyCol = D2.PrimaryKeyCol
Where S2.mid = S1.mid
)
Group By S1.mid
) As LastStateChange
On LastStateChange.mid = M.mid
Left Join statechange As S
On S.PrimaryKeyCol = LastStateChange.PrimaryKeyCol
Left Join dates As D
On D.PrimaryKeyCol = S.DatesForeignKeyCol
One of the reasons I used the above approach is to account for the scenario where you might have multiple statechange
rows for the same mid
and date
value. The above approach will use the primary key column as the tie-breaker in that scenario.
精彩评论