你可以做到這一點使用Gaps and Islands邏輯:
SELECT VehicleID, Connected, MIN(Date) AS Date
FROM ( SELECT *,
DENSE_RANK() OVER(PARTITION BY VehicleID ORDER BY Date) -
DENSE_RANK() OVER(PARTITION BY VehicleID, Connected ORDER BY Date) AS GroupingSet,
MIN(CASE WHEN Connected THEN Date END) OVER(PARTITION BY VehicleID) AS FirstConnected
FROM status
WHERE VehicleID = 'redcar'
AND date >= '2014-02-28 00:00:00'
AND date < '2014-03-01 00:00:00'
) s
WHERE Date > FirstConnected
GROUP BY VehicleID, Connected, GroupingSet
Example on SQL Fiddle
如果您還需要檢索StatusID
你將需要添加一個進一步排序功能,只只選擇第一行:
SELECT StatusID,
VehicleID,
Connected,
Date
FROM ( SELECT StatusID,
VehicleID,
Connected,
Date,
ROW_NUMBER() OVER(PARTITION BY VehicleID, Connected, GroupingSet ORDER BY Date) AS RowNumber
FROM ( SELECT *,
DENSE_RANK() OVER(PARTITION BY VehicleID ORDER BY Date) -
DENSE_RANK() OVER(PARTITION BY VehicleID, Connected ORDER BY Date) AS GroupingSet,
MIN(CASE WHEN Connected THEN Date END) OVER(PARTITION BY VehicleID) AS FirstConnected
FROM status
WHERE VehicleID = 'redcar'
AND date >= '2014-02-28 00:00:00'
AND date < '2014-03-01 00:00:00'
) s
WHERE Date > FirstConnected
) s
WHERE RowNumber = 1;
Example on SQL Fiddle
或者使用DISTINCT ON
:
SELECT DISTINCT ON (VehicleID, Connected, GroupingSet)
StatusID,
VehicleID,
Connected,
Date
FROM ( SELECT *,
DENSE_RANK() OVER(PARTITION BY VehicleID ORDER BY Date) -
DENSE_RANK() OVER(PARTITION BY VehicleID, Connected ORDER BY Date) AS GroupingSet,
MIN(CASE WHEN Connected THEN Date END) OVER(PARTITION BY VehicleID) AS FirstConnected
FROM status
WHERE VehicleID = 'redcar'
AND date >= '2014-02-28 00:00:00'
AND date < '2014-03-01 00:00:00'
) s
WHERE Date > FirstConnected
ORDER BY VehicleID, Connected, GroupingSet
Example on SQL Fiddle
你的回答很有效。它以期望的順序給出所需的數據。但是,我想要檢索STATUS表中的所有字段。此外,這個答案是否適用於Hibernate?謝謝。 – nudaStck
如果該表的列數多於所示的4,那麼只需將'SELECT statusId,vehicleId,connected,date'(兩次)替換爲所需的列。不知道Hibernate,對不起。 –
非常感謝您的回答。我將發佈另一個與Hibernate相關的問題。 – nudaStck