简体   繁体   English

MariaDB:Select 每个项目每月平均(数据透视表)

[英]MariaDB: Select average per month per item (Pivot table)

I have MariaDB table that looks like this:我有看起来像这样的 MariaDB 表:

Component零件 Timestamp时间戳 Duration期间
Component one组件一 2021-10-01 14:04:54 2021-10-01 14:04:54 40 40
Component one组件一 2021-11-01 14:04:45 2021-11-01 14:04:45 10 10
Component one组件一 2021-11-11 11:05:23 2021-11-11 11:05:23 20 20
Component one组件一 2021-12-01 13:04:43 2021-12-01 13:04:43 20 20
Component one组件一 2021-12-12 12:14:11 2021-12-12 12:14:11 30 30
Component two组件二 2021-11-01 14:04:27 2021-11-01 14:04:27 45 45
Component two组件二 2021-12-01 13:04:08 2021-12-01 13:04:08 23 23

What I'd like to do is show the average duration of each component over the last three months.我想做的是显示过去三个月每个组件的平均持续时间。 It should look something like this:它应该看起来像这样:

Component零件 AVG Duration (October)平均持续时间(10 月) AVG Duration (November)平均持续时间(11 月) AVG Duration (December)平均持续时间(十二月)
Component one组件一 40 40 15 15 25 25
Component two组件二 45 45 23 23

I tried messing around with a pivot table I found online, but the below query still results in multiple lines (1 for each month, with the other months empty on that line)我试着弄乱我在网上找到的 pivot 表,但下面的查询仍然导致多行(每个月 1 行,其他月份该行为空)

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
               CONCAT('(IF(MONTHNAME(s.LOG_TIMESTAMP) = "', MONTHNAME(`LOG_TIMESTAMP`),'", AVG(`DURATION`),"")) AS ',MONTHNAME(LOG_TIMESTAMP) )
              ) INTO @sql
FROM table1;


SET @sql = CONCAT('SELECT s.COMPONENT,  ', @sql, ' 
                  FROM table1 s
                 GROUP BY s.COMPONENT, MONTHNAME(s.LOG_TIMESTAMP)
                 ORDER BY s.COMPONENT');
SELECT @sql;
PREPARE stmt FROM @sql;
EXECUTE stmt;

So if I run that query the output for component 1 (for example) is like this:因此,如果我运行该查询,组件 1(例如)的 output 是这样的:

Component零件 AVG Duration (October)平均持续时间(10 月) AVG Duration (November)平均持续时间(11 月) AVG Duration (December)平均持续时间(十二月)
Component one组件一 40 40
Component one组件一 15 15
Component one组件一 25 25

It's probably the group-by expression having the log_timestamp, but if I remove that one the concat function just writes the average duration (of all months) in the first available month.它可能是具有 log_timestamp 的 group-by 表达式,但如果我删除它,concat function 只会写入第一个可用月份的平均持续时间(所有月份)。 I don't have any experience with pivotting tables so I'm a bit out of my depth here.我对数据透视表没有任何经验,所以我在这里有点超出我的深度。 Any help would be appreciated.任何帮助,将不胜感激。

Do it in 2 steps:分两步进行:

  1. Write a query to compute the averages.编写一个查询来计算平均值。
  2. Write a query to pivot, using the step-1 query in a 'derived table'.使用“派生表”中的步骤 1 查询向 pivot 写入查询。

Perhaps a final query like this:也许像这样的最终查询:

SELECT Component,
       MAX(IF(mth=10,avgd,0)) AS 'October',
       MAX(IF(mth=11,avgd,0)) AS 'November',
       MAX(IF(mth=12,avgd,0)) AS 'December'
 FROM
(SELECT Component,
       MONTH(LOG_TIMESTAMP) mth,
       AVG(Duration) Avgd
FROM table1
GROUP BY Component, mth) v
GROUP BY Component;

And prepared statement syntax of the following:并准备了以下语句的语法:

SET @sql := NULL;

SELECT CONCAT('SELECT Component,',
       GROUP_CONCAT(CONCAT('
       MAX(IF(mth=',mth,',avgd,0)) AS "',mthname,'"') 
       SEPARATOR ','),
       '
FROM (SELECT Component,
       MONTH(LOG_TIMESTAMP) mth,
       AVG(Duration) Avgd
FROM table1
GROUP BY Component, mth) v
GROUP BY Component') INTO @sql
FROM
(SELECT DISTINCT MONTH(LOG_TIMESTAMP) mth, 
       MONTHNAME(LOG_TIMESTAMP) mthname
FROM table1) a;

SELECT @sql;

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

Demo fiddle 演示小提琴

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

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