我有此查询需要0.04秒的加载时间
SELECT sg.Name AS 'Customer Name',
m.meter_id AS 'Serial No',
DATE_FORMAT(datetime, '%Y/%m/%d') AS Date,
MAX(wh_total) AS Present
FROM meter_data m
INNER JOIN enrollment e
ON e.Meter_Id = m.meter_id AND e.Status = 1
INNER JOIN company_subgroup sg
ON sg.Id = e.Subgroup_Id
INNER JOIN company_group g
ON g.Id = sg.Group_Id
WHERE date(dateTime) BETWEEN '2018/06/01' AND '2018/06/30'
AND m.meter_id = '12345'
AND m.wh_total < 1000000000
GROUP BY date(datetime)
但是,如果我添加了此“上一个”选择列,则执行该操作大约需要20秒。
SELECT sg.Name AS 'Customer Name',
m.meter_id AS 'Serial No',
DATE_FORMAT(datetime, '%Y/%m/%d') AS Date,
// THIS (main issue)
COALESCE((SELECT MAX(wh_total) FROM meter_data WHERE date(dateTime) < date(m.dateTime) AND meter_id = '12345'
AND wh_total < 1000000000 GROUP BY date(dateTime) ORDER BY date(dateTime) DESC LIMIT 1),0) AS Previous,
//
MAX(wh_total) AS Present,
// THIS (But I guess this does not affect the query that much since it only substract the two columns)
ROUND(MAX(wh_total) - MIN((SELECT Previous)),2) AS Consumption
//
FROM meter_data m
INNER JOIN enrollment e
ON e.Meter_Id = m.meter_id AND e.Status = 1
INNER JOIN company_subgroup sg
ON sg.Id = e.Subgroup_Id
INNER JOIN company_group g
ON g.Id = sg.Group_Id
WHERE date(dateTime) BETWEEN '2018/06/01' AND '2018/06/30'
AND m.meter_id = '12345'
AND m.wh_total < 1000000000
GROUP BY date(datetime)
基本上,Previous列获取上一行的数据。查询看起来像这样:
Customer Name | Serial No | Date | Previous | Present | Consumption
ABC | 12345 | 06/01/2018 | 0 | 1 | 1
ABC | 12345 | 06/02/2018 | 1 | 3 | 2
ABC | 12345 | 06/03/2018 | 3 | 8 | 5
ABC | 12345 | 06/04/2018 | 8 | 10 | 2
不幸的是,我尝试使用LAG(column)来获取上一行数据,不幸的是MySQL版本是5.6。有什么方法可以优化此查询?
答案 0 :(得分:0)
尝试一下
SELECT sg.Name AS 'Customer Name',
m.meter_id AS 'Serial No',
DATE_FORMAT(datetime, '%Y/%m/%d') AS Date,
COALESCE(mx.max_total,0) AS Previous,
MAX(wh_total) AS Present,
ROUND(MAX(wh_total) - MIN((mx.max_total)),2) AS Consumption
FROM meter_data m
INNER JOIN enrollment e ON e.Meter_Id = m.meter_id AND e.Status = 1
INNER JOIN company_subgroup sg ON sg.Id = e.Subgroup_Id
INNER JOIN company_group g ON g.Id = sg.Group_Id
LEFT JOIN (SELECT date(dateTime) as dt, MAX(wh_total) max_total
FROM meter_data
WHERE meter_id = '12345' AND wh_total < 1000000000
GROUP BY date(dateTime)) mx on mx.dt < date(m.dateTime)
WHERE date(m.dateTime) BETWEEN '2018/06/01' AND '2018/06/30'
AND m.meter_id = '12345'
AND m.wh_total < 1000000000
GROUP BY date(m.datetime)
注意:如果该内联返回多于一行,则通过添加更多条件来限制该行
答案 1 :(得分:0)
尝试此查询。它将先前的数据存储在用户变量中。
我再次更改了它。 MAX函数出现错误。所以我把它 在子查询中。
SELECT r.`Customer NAME`, r.`SERIAL NO`, r.`DATE` , @prev AS Previous , @reav := r.`Present`
FROM (
SELECT sg.Name AS `Customer NAME`,
m.meter_id AS `SERIAL NO`,
DATE_FORMAT(DATETIME, '%Y/%m/%d') AS `DATE`,
MAX(wh_total) AS `Present`
FROM meter_data m
INNER JOIN enrollment e
ON e.Meter_Id = m.meter_id AND e.Status = 1
INNER JOIN company_subgroup sg
ON sg.Id = e.Subgroup_Id
INNER JOIN company_group g
ON g.Id = sg.Group_Id
WHERE DATE(DATETIME) BETWEEN '2018/06/01' AND '2018/06/30'
AND m.meter_id = '12345'
AND m.wh_total < 1000000000
GROUP BY DATE(DATETIME)
) AS r
CROSS JOIN (SELECT @prev:=0) AS INIT;