生成报告的MySql查询

3

我有一个表格,其中有三个字段:

Id, Creation Time, Fuel Level

每两分钟我们都会获得数据并将其插入到数据库中。为了生成燃料信用/借记报表,我想要获取当天的起始(一天的开始)和结束(一天的结束)燃料水平。有人能帮忙编写一个查询来生成这个报告吗?
搜索参数将是日期范围。
Id = 10;创建时间=2019-02-15 16:32:59;燃料水平=20
我在这里创建了一个示例模式 http://sqlfiddle.com/#!2/76dd5

请给我们一个带有数据的示例。 - Rahul Agrawal
请尝试自行解决问题,并展示当前的代码、输出结果以及您期望的输出结果。这将有助于我们找到解决方案。 - Konza
3个回答

4

首先,如果您需要查询每辆车每天的燃料消耗量变化,请使用以下SQL语句:

SELECT trip_range.dt
     , trip_range.vehicle_id
     , st.fuel_content as start_fuel_content
     , en.fuel_content as end_fuel_content
     , en.fuel_content - st.fuel_content as fuel_change
  FROM (
SELECT tp.vehicle_id, DATE(tp.creation_time) dt
     , MIN(tp.creation_time) start_time
     , MAX(tp.creation_time) end_time
  FROM trip_parameters tp
 GROUP BY tp.vehicle_id, DATE(tp.creation_time)
) as trip_range
  JOIN trip_parameters st
    ON st.vehicle_id = trip_range.vehicle_id
       AND st.creation_time = trip_range.start_time
  JOIN trip_parameters en
    ON en.vehicle_id = trip_range.vehicle_id
       AND en.creation_time = trip_range.end_time
 WHERE trip_range.dt BETWEEN '2012-11-08' AND '2012-11-09'

如果您想要在日期范围内获得所有车辆燃料的累计变化量,以下SQL语句应该可以实现:
SELECT dt, SUM(fuel_change) as fuel_change
  FROM (
SELECT trip_range.dt
     , en.fuel_content - st.fuel_content as fuel_change
  FROM (
SELECT tp.vehicle_id, DATE(tp.creation_time) dt
     , MIN(tp.creation_time) start_time
     , MAX(tp.creation_time) end_time
  FROM trip_parameters tp
 GROUP BY tp.vehicle_id, DATE(tp.creation_time)
) as trip_range
  JOIN trip_parameters st
    ON st.vehicle_id = trip_range.vehicle_id
       AND st.creation_time = trip_range.start_time
  JOIN trip_parameters en
    ON en.vehicle_id = trip_range.vehicle_id
       AND en.creation_time = trip_range.end_time
 WHERE trip_range.dt BETWEEN '2012-11-08' AND '2012-11-09'
) change_by_vehicle
 GROUP BY 1

希望这能帮到你! 约翰...

请提供更多信息,例如表模式、示例行和示例输出。或者,转到 http://sqlfiddle.com/ 并创建带有一些样本数据的表。然后将结果 URL 发布给我们进行“摆弄”。 - John Fowler
我在 SQLFiddle 中创建了一个查询..下面是链接 http://sqlfiddle.com/#!2/76dd5 - vmb
谢谢。Sqlfiddle可以帮助解释很多东西。我已经相应地更新了我的答案。你可以在sqlfiddle中运行我提供的两个查询。 - John Fowler
非常感谢。查询非常有效。现在我面临的问题是这个查询的执行时间相当长(几分钟)。trip_parameters表中包含了超过5万条记录。我还有一个疑问,是否有办法找到每天车辆的加油量?如果一辆车在两行之间的燃料水平差超过2,则认为它是加油,并通过减去这些行来得到加油量。另外,同一天可能发生多次加油。所以我需要每天的总加油量(每辆车)。是否有可能使用查询来处理这个问题? - vmb
我建议您修改我提供的第一个查询,以根据您的新标准确定每辆车每天加油量。至于速度,我建议在vehicle_id和creation_time上创建索引,并将日期过滤条件移入内部SELECT。由于GROUP BY DATE(...)子句,查询可能运行缓慢,但除了创建另一个字段来保存“日期”并在其上创建索引外,没有其他办法。 - John Fowler
我没有找到获取加油量的解决方案...但我会接受你的解决方案...谢谢。 - vmb

1

请尝试以下:

   SELECT Id, CreationTime, FuelLevel
   FROM MYTABLE
   WHERE DATE(CreationTime) = CURDATE();

此代码获取CreationTime的日期部分并与当前日期进行比较,因此返回所有今天创建的记录。


1
这是一个查询,返回的输出如下:
DATE            FUEL_CONTENT_AT_START_OF_DAY    FUEL_CONTENT_AT_END_OF_DAY
Nov, 08 2012    4.6                             3.6
Nov, 09 2012    11.6                            5.6

Query

SELECT
    DATE( startofday.creation_time) AS date,
    startofday.fuel_content AS fuel_content_at_start_of_day,
    (SELECT fuel_content FROM trip_parameters WHERE trip_paramid = max(endofday.trip_paramid) ) AS fuel_content_at_end_of_day
FROM
    trip_parameters startofday
    INNER JOIN trip_parameters endofday ON ( DATE( endofday.creation_time ) = DATE( startofday.creation_time) )
WHERE
    DATE( startofday.creation_time) BETWEEN '2012-11-08'  AND '2012-11-09'
GROUP BY
    startofday.TRIP_PARAMID
HAVING
  min( endofday.trip_paramid ) = startofday.trip_paramid

我已在 SQLFiddle 上更新了相同的内容,http://sqlfiddle.com/#!2/76dd5/67 查询操作如下:
  • 获取一行数据
    • 获取同一天内的所有相关行
    • 获取同一天内最小和最大 ID
  • 如果当前行的 ID 等于 JOIN 中的最小 ID,则显示它;否则忽略它
    • 使用子查询中的最大 ID 获取当天燃料容量的结束值
希望这能帮到你。

是否可以使用HQL查询来实现同样的功能? - vmb
最好直接使用原始SQL来执行复杂查询。对于这样的事情使用ORM可能会使它变得更慢和更难理解。 - Akash

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接