限制mysql查询中的记录数

时间:2013-06-04 11:48:49

标签: asp.net mysql sql

我写了一个查询:

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

但问题是它为每个between子句返回多个记录,但我只想要一个。对于整个查询,LIMIT将限制总记录= 1。所以不能用那个。请帮忙!

2 个答案:

答案 0 :(得分:0)

使用一系列UNIONed查询: -

(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类

多次传递它们

另一种可能性(但未经过测试)是让subselect获取meter id / device id的每个范围内的最大时间戳,添加CASE语句以获取行的范围并按其分组,然后加入结果反对主表。

请注意,如果仪表ID /设备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

答案 1 :(得分: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“列”。这只是选择遇到的第一个值。