您好,我有一个桌子,该桌子由我的家庭自动化设备填充。 我原则上只有一张表包含所有值。 一些条目是通过统计模块进行的。它计算每月的用水量。 现在,我想创建一个查询,以提供每年消耗量的详细视图。
赞:
|Month|2018|2019|
|Jan..|7.3 |6.8|
|Feb |5.9 |7.8|....
查询一年:
SELECT
monthname(TIMESTAMP) Monat,
VALUE '2018'
FROM
fhem.history acht
WHERE
DEVICE LIKE 'Wasserverbrauch'
AND READING LIKE 'statStateMonthLast'
AND year(TIMESTAMP) = 2018
但是我如何才能加入2019年的价值观呢?有人可以指出我正确的方向吗?
谢谢,
鲁迪格(Ruediger)
答案 0 :(得分:1)
您可以进行条件聚合:
SELECT
MONTHNAME(timestamp) Monat,
MAX(CASE WHEN timestamp >= '2018-01-01' AND timestamp < '2019-01-01' THEN value END) `2018`,
MAX(CASE WHEN timestamp >= '2019-01-01' AND timestamp < '2020-01-01' THEN value END) `2019`
FROM fhem.history acht
WHERE
device = 'Wasserverbrauch'
AND reading = 'statStateMonthLast'
AND timestamp >= '2018-01-01'
AND timestamp < '2020-01-01'
GROUP BY MONTHNAME(timestamp)
注意:
LIKE
子句中的WHERE
条件实际上等效于=
,因为正确的操作数中没有通配符;我相应地更改了它们
通常最好进行显式的日期时间范围比较,而不要使用日期函数(在您的情况下为year()
),因为后者会阻止使用索引
如果您每个月需要处理多个记录员(根据您现有的查询来看似乎不是这种情况),则应该使用另一个聚合函数来获得更明智的结果(sum()
或avg()
)
答案 1 :(得分:0)
您可以使用EXTRACT()函数从时间戳获取年/月,并使用条件表达式将其全部放入列中。
我认为带有月份数字和名称的表对于外部联接很有用。
SELECT
m.`month`,
SUM(IF(h.`year_no`=2019, h.`value`, 0)) AS `2019`,
SUM(IF(h.`year_no`=2020, h.`value`, 0)) AS `2020`
FROM `monthes` AS m
LEFT JOIN (
SELECT
EXTRACT(YEAR FROM `timestamp`) AS `year_no`,
EXTRACT(MONTH FROM `timestamp`) AS `month_no`,
`value`
FROM `history`
) AS h ON h.`month_no` = m.`id`
GROUP BY m.`id`
我使用了GROUP BY月份ID,因此结果将按月份编号而不是月份名称隐式排序。
https://www.db-fiddle.com/f/78LQtak6GwkDS8pzredroQ/0
为求勇敢,我在这里没有使用其他过滤器,但是如果需要它们,请将WHERE...
添加到嵌套子查询的右侧FROM history
下。
答案 2 :(得分:0)
这是GMB回答的变体。但是,如果您希望结果按时间顺序按月排列,则需要在查询中包括:
SELECT MONTHNAME(timestamp) as Monat,
SUM(CASE WHEN YEAR(timestamp) = 2018 THEN value END) value_2018,
SUM(CASE WHEN YEAR(timestamp) = 2019 THEN value END) as value_2019
FROM fhem.history acht
WHERE device = 'Wasserverbrauch' AND
reading = 'statStateMonthLast' AND
timestamp >= '2018-01-01' AND
timestamp < '2020-01-01'
GROUP BY MONTHNAME(timestamp), MONTH(timestamp)
ORDER BY MONTH(timestamp);