繁体   English   中英

用更好的方式编写此SQL查询的一种好方法是什么?

[英]What would be a good way to write this SQL query in a better way?

SELECT
    MAX(timestamp) as end,
    MIN(timestamp) as start, 
    (MAX(odometerKM) - MIN(odometerKM)) as distanceTravelled,
    ( SELECT COUNT(*) FROM EventData WHERE speedKPH = 0 AND timestamp >= ? AND timestamp <= ? AND  deviceID = ?)  as stopsDuration,
    ( SELECT COUNT(*) FROM EventData WHERE speedKPH != 0 AND timestamp >= ? AND timestamp <= ? AND  deviceID = ? )  as tripDuration,
    (MAX(odometerKM) - MIN(odometerKM)) / ( SELECT fuelEconomy FROM Device WHERE deviceID = ?) as fuelConsumption
FROM EventData
WHERE deviceID = ? AND timestamp >= ? AND timestamp <= ?

相当令人困惑,但是我创建了此查询来查找行集的摘要。 最小和最大时间戳很简单,但是要找到速度为零而不是零的COUNT行,我做了一个丑陋的修改。 我确定有更好的方法可以做到这一点?

更新 :“?” 会被CodeIgniter的一个不成熟的查询生成器取代。 可悲的是,它还不支持命名参数。

您应该包括DeviceID,这样才有意义。 尝试这个:

SELECT
DeviceID,
MAX(timestamp) as end,
MIN(timestamp) as start, 
(MAX(odometerKM) - MIN(odometerKM)) as distanceTravelled,
SUM (
  case speedKPH 
    when  0  then 1
    else 0
  end)  as stopsDuration,

SUM (
  case speedKPH 
    when  0  then 0
    else 1
  end)  as tripDuration,

(MAX(odometerKM) - MIN(odometerKM)) / Device.fuelEconomy  as fuelConsumption

FROM EventData
Join Device ON Device.deviceID = EventData.deviceID 

WHERE deviceID = ? AND timestamp >= ? AND timestamp <= ?

GROUP BY  DeviceID

我会摆脱列子查询。 您可以像这样计算stopsDurationtripDuration (我fuelConsumption不考虑fuelConsumption ):

SELECT
  MAX(timestamp) as end, MIN(timestamp) as start, 
  MAX(odometerKM) - MIN(odometerKM) as distanceTravelled,
  COUNT(speedKPH = 0 AND timestamp >= ? AND timestamp <= ?) as stopsDuration
  COUNT(speedKPH != 0 AND timestamp >= ? AND timestamp <= ?) as tripDuration
FROM EventData WHERE deviceID = ? AND timestamp >= ? AND timestamp <= ?

您可以通过交叉连接到Device表的单个适用行来摆脱fuelComparison子查询

SELECT
  (MAX(odometerKM) - MIN(odometerKM)) / dv.fuelEconomy as fuelConsumption
FROM
  EventData,
  (SELECT Device.fuelEconomy FROM Device WHERE DeviceId = ?) dv
WHERE deviceID = ? AND timestamp >= ? AND timestamp <= ?

将所有内容放在一起,您将得到(至少在纸上)应该更快的效果:

SELECT
  MAX(timestamp) as end, MIN(timestamp) as start, 
  MAX(odometerKM) - MIN(odometerKM) as distanceTravelled,
  COUNT(speedKPH = 0 AND timestamp >= ? AND timestamp <= ?) as stopsDuration
  COUNT(speedKPH != 0 AND timestamp >= ? AND timestamp <= ?) as tripDuration,
  (MAX(odometerKM) - MIN(odometerKM)) / dv.fuelEconomy as fuelConsumption
FROM
  EventData,
  (SELECT Device.fuelEconomy FROM Device WHERE DeviceId = ?) dv
WHERE deviceID = ? AND timestamp >= ? AND timestamp <= ?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM