2013-06-04 116 views
0

我寫了一個查詢:限制的記錄數在MySQL查詢

SELECT TimeStamp, FwdHr, W FROM Meter_Data 
WHERE TimeStamp Between 1356908255 AND 1356944255 
OR (TimeStamp BETWEEN 1356911855 AND 1356947855) 
OR (TimeStamp BETWEEN 1356915455 AND 1356951455) 
OR (TimeStamp BETWEEN 1356919055 AND 1356955055) 
OR (TimeStamp BETWEEN 1356922655 AND 1356958655) 
AND MeterID = @meterID 
AND DeviceID = @deviceID 
ORDER BY TimeStamp 

,但問題是,它返回多個記錄,每節之間,但我只想要一個。 LIMIT將限制整個查詢的總記錄數= 1。所以不能使用它。請幫忙!

+1

你如何決定在每個範圍內採用哪個時間戳/ fwdhr/w? – Dibstar

+1

請注意,'MeterID'和'DeviceID'只針對最後一個'TimeStamp'範圍進行檢查。如果你想讓它們檢查所有'TimeStamp'範圍,但'TimeStamp'範圍內的括號(在'WHERE'之後和第一個'AND'之前)。 – Olexa

+0

您可以按照FwdHr和Max(TimeStamp) 這就是你想要的嗎?你需要其他領域嗎? – Mzf

回答

0

使用一系列聯合在一起的查詢: -

(SELECT TimeStamp, FwdHr, W 
FROM Meter_Data 
WHERE TimeStamp Between 1356908255 AND 1356944255 
AND MeterID = @meterID 
AND DeviceID = @deviceID 
ORDER BY TimeStamp 
LIMIT 1) 
UNION 
(SELECT TimeStamp, FwdHr, W 
FROM Meter_Data 
WHERE TimeStamp BETWEEN 1356911855 AND 1356947855 
AND MeterID = @meterID 
AND DeviceID =  @deviceID 
ORDER BY TimeStamp 
LIMIT 1) 
UNION 
(SELECT TimeStamp, FwdHr, W 
FROM Meter_Data 
WHERE TimeStamp BETWEEN 1356915455 AND 1356951455 
AND MeterID = @meterID 
AND DeviceID =  @deviceID 
ORDER BY TimeStamp 
LIMIT 1) 
UNION 
(SELECT TimeStamp, FwdHr, W 
FROM Meter_Data 
WHERE TimeStamp BETWEEN 1356919055 AND 1356955055 
AND MeterID = @meterID 
AND DeviceID =  @deviceID 
ORDER BY TimeStamp 
LIMIT 1) 
UNION 
(SELECT TimeStamp, FwdHr, W 
FROM Meter_Data 
WHERE TimeStamp BETWEEN 1356922655 AND 1356958655 
AND MeterID = @meterID 
AND DeviceID =  @deviceID 
ORDER BY TimeStamp 
LIMIT 1) 

您可能需要根據多次DB類更改參數名稱,並通過他們對你

另一種可能性(但沒有測試過)會要有一個子選擇器獲取儀表ID /設備ID的每個範圍內的最大時間戳,添加一個CASE語句來獲取某一行所在的範圍並按該範圍進行分組,然後將結果與主表連接起來。

請注意,如果有米秒/設備ID組合的重複時間戳,那麼這將無法正常工作。

不知道這會更快還是更慢!

SELECT Meter_Data.TimeStamp, Meter_Data.FwdHr, Meter_Data.W 
FROM Meter_Data 
INNER JOIN (SELECT MAX(TimeStamp) AS MaxTimestamp, MeterID, DeviceID, 
CASE 
    WHEN TimeStamp Between 1356908255 AND 1356944255 THEN 1 
    WHEN TimeStamp BETWEEN 1356911855 AND 1356947855 THEN 2 
    WHEN TimeStamp BETWEEN 1356915455 AND 1356951455 THEN 3 
    WHEN TimeStamp BETWEEN 1356919055 AND 1356955055 THEN 4 
    WHEN TimeStamp BETWEEN 1356922655 AND 1356958655 THEN 5 
END AS GroupNo 
FROM Meter_Data 
WHERE (TimeStamp Between 1356908255 AND 1356944255 
OR TimeStamp BETWEEN 1356911855 AND 1356947855 
OR TimeStamp BETWEEN 1356915455 AND 1356951455 
OR TimeStamp BETWEEN 1356919055 AND 1356955055 
OR TimeStamp BETWEEN 1356922655 AND 1356958655) 
AND MeterID = @meterID 
AND DeviceID = @deviceID 
GROUP BY MeterID, DeviceID, GroupNo) Sub1 
ON Meter_Data.MeterID = Sub1.MeterID 
AND Meter_Data.DeviceID = Sub1.DeviceID 
AND Meter_Data.TimeStamp = Sub1.MaxTimestamp 
ORDER BY Meter_Data.TimeStamp 
+0

不會影響性能嗎? –

+0

它應該相當有效。我想不出一種更有效的方法 – Kickstart

+0

使用進一步的解決方案進行編輯 – Kickstart

0

在MySQL中,您可以使用變量來做到這一點。以下是一種方法:

SELECT TimeStamp, FwdHr, W 
FROM (select md.*, 
      (case when TimeStamp Between 1356908255 AND 1356944255 then @rn1 := @rn1 + 1 
        when TimeStamp BETWEEN 1356911855 AND 1356947855 then @rn2 := @rn2 + 1 
        when TimeStamp BETWEEN 1356915455 AND 1356951455 then @rn3 := @rn3 + 1 
        when TimeStamp BETWEEN 1356919055 AND 1356955055 then @rn4 := @rn4 + 1 
        when TimeStamp BETWEEN 1356922655 AND 1356958655 then @rn5 := @rn5 + 1 
       end) as rn 
     from Meter_Data cross join 
      (select @rn1 := 0, @rn2 := 0, @rn3 := 0, @rn4 := 0, @rn5 := 0) const 
     WHERE MeterID = @meterID AND DeviceID = @deviceID 
    ) md 
where rn = 1 
ORDER BY TimeStamp; 

這爲每個組定義了一個單獨的變量。然後在看到變量時增加變量,將結果返回rn「列」。這只是選擇遇到的第一個值。

+0

不幸的是,這會受到同樣的影響(如我和OP所討論的),時間戳範圍可能會重疊,但它是一種乾淨利落的做事方式。 – Kickstart