【问题标题】:SQL Average of fields based on conditions基于条件的字段的 SQL 平均值
【发布时间】:2023-03-18 17:11:02
【问题描述】:

我正在创建一个报告工具,它有一个我想在 SQL 世界中解决的特定要求。我正在使用 MySQL 5.6.11: 我们有一些输入可以不引入,一天一到两次:

DATETIME            | VALUE

01-01-2015 00:10:11 |   5 
01-03-2015 00:11:11 |   3
01-03-2015 00:12:11 |   4
01-03-2015 00:11:11 |   5
01-03-2015 00:12:11 |   8

我想通过以下方式获得平均值:

DATETIME   | FIRST INSERTED VALUE AVERAGE | SECOND INSERTED VALUE AVERAGE
01-01-2015 |          5                   | null
01-03-2015 |          4                   | 6

我们对所有记录的平均值感兴趣,但时间很重要。 我们想要在特定日期为一列中的所有报告引入的第一个值的平均值,以及第二个引入的第二个值(如果有)的平均值。

这是一个不考虑第一个值和第二个值之间差异的报告示例

SELECT AVG(bt.value), DATE(bt.date) 
    FROM reports bt
    GROUP BY DATE(bt.date) 

【问题讨论】:

  • 您究竟打算如何进行计算?好的值平均值=数字总和/总数,这意味着第一个记录中的值为 1,第二个必须为 4,但你说的是 3,那么 second_value 平均值是如何计算的?请详细说明您要做什么..
  • 你必须解释什么是第一和第二平均价值
  • 刚刚编辑了更多解释。谢谢!
  • 仍然不明白你为什么称它为平均值,从你的表述来看,它似乎只是按顺序添加的第一个和第二个值
  • @Ammadu 你是对的,这并不明显,我只是更新了示例

标签: mysql sql database relational-database reporting


【解决方案1】:

像这样执行转置操作相当困难,但我认为使用GROUP_CONCAT可以得到你想要的。

首先,您必须按完整的 DATETIME 对结果进行分组,然后您可以再次按 DATE 部分进行分组,同时将结果连接到平均值列中。最终的 SELECT 会将连接的字符串解析为不同的列。

SELECT date, SUBSTRING_INDEX(averages, '#', 1) FIRST,
   if (averages_count >= 2, SUBSTRING_INDEX(SUBSTRING_INDEX(averages, '#', 2), '#', -1), NULL) SECOND

FROM (SELECT DATE(derived.date) AS date, GROUP_CONCAT(derived.average SEPARATOR '#') AS averages, COUNT(*) AS averages_count
          FROM (SELECT bt.date AS date, AVG(bt.value) AS average
                    FROM reports AS bt
                    GROUP BY bt.date) AS derived
          GROUP BY DATE(date)) AS base

(我的灵感来自this answer)。

【讨论】:

  • 其实这并不完全正确。它没有计算第二种类型的正确平均值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多