【问题标题】:MySQL grouping when using a sub query使用子查询时的 MySQL 分组
【发布时间】:2019-11-04 17:38:05
【问题描述】:

我正在尝试创建一个汇总输出以根据子查询中的值显示总计,然后按标签对输出进行分组

查询如下:

select c.name,
(select sum(duration) from dates d 
inner join time t1 on d.time_id=t1.id 
where d.employee=t.employee 
and d.date >= now() - INTERVAL 12 MONTH) as ad,    
(select sum(cost) from dates d 
inner join time t1 on d.time_id=t1.id 
where d.employee=t.employee 
and d.date >= now() - INTERVAL 12 MONTH) as ac

FROM time t

inner join employees ee on t.employee=ee.employee
inner join centres c on ee.centre=c.id 
where 
ee.centre in (4792,4804,4834) group by c.centre

我希望它显示每个中心的广告和 ac,但它只显示列表中最后一个中心的 ac 值,其余显示为零

如果我删除该组,然后我会得到所有条目的列表,但它不会以任何方式汇总,我需要那个汇总视图

【问题讨论】:

  • 可能学会正确地格式化你的代码,并学会使用正确的GROUP BY。您的代码甚至不会在其他 dbms 中运行。即使是较新版本的 MySQL 也不会运行您的代码。
  • 如果目标是得到centre 的总数,您似乎希望在子查询中加入employeescentres。如果没有示例数据和示例输出,我们所要做的就是返回意外结果的 SQL。如果没有规范,我们只是在猜测需求,我们可能提出的任何 SQL 更改都只是猜测。
  • 我认为问题的症结在于GROUP BY 正在折叠行,而折叠的集合包括具有各种t.employee 值的行。 MySQL 特定的非标准扩展允许查询运行而不会引发错误;对于折叠集,相同的扩展只获得了 t.employee 的单个值,这就是传递给 SELECT 列表中的子查询的值。但是(再次)没有规范,我们只是猜测这个查询应该实现什么。

标签: mysql group-by subquery


【解决方案1】:

返回意外结果的 SQL 语句不是很多。

如果没有规范,通过示例数据和预期输出进行有用的说明,我们只是猜测查询应该达到的结果。

我认为问题的症结在于为GROUP BY 返回的t.employee 的值,对于t.employee 的每个值,具有各种t.employee 值的多个详细信息行被折叠成一行c.centret.employee 的值来自集合中的“某行”。 (特定于 MySQL 的非标准扩展允许查询运行而不会抛出错误,而其他 RDBMS 会抛出错误。我们可以通过在 `sql_mode 中包含 ONLY_FULL_GROUP_BY 来使 MySQL 行为更符合标准。但这只会导致问题中的 SQL 抛出错误。)

建议的解决方法(只是猜测)是在执行 GROUP BY 之前为每个员工派生 acad,然后进行聚合。

(我仍然怀疑centre 的连接,不包含在子查询中。employee 是主键还是employees 中的唯一键?centre 在功能上依赖于employee ? 太多的问题,太多的假设。

我的猜测是我们在查询返回的结果是这样的:

SELECT c.name
     , SUM(v.ad) AS `ad`
     , SUM(v.ac) AS `ac`
  FROM ( -- derive `ad` and `ac` in an inline view before we collapse rows 
         SELECT ee.employee
              , ee.centre
              , ( -- derived for each employee
                  SELECT SUM(d1.duration)
                    FROM time t1
                    JOIN dates d1
                      ON d1.time_id = t1.id
                     AND d1.date >= NOW() + INTERVAL -12 MONTH
                   WHERE d1.employee = t.employee
                ) AS `ad`
              , ( -- derived for each employee
                  SELECT SUM(d2.cost)
                    FROM time t2
                    JOIN dates d2
                      ON d2.time_id = t2.id
                     AND d2.date >= NOW() + INTERVAL -12 MONTH
                   WHERE d2.employee = t.employee
                ) AS `ac`
           FROM time t
           JOIN employees ee
             ON ee.employee = t.employee
          WHERE ee.centre in (4792,4804,4834)
          GROUP
             BY ee.employee
              , ee.centre
      ) v
 LEFT
 JOIN centres c
   ON c.id = v.centre
GROUP
   BY v.centre
    , c.name

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-24
    • 1970-01-01
    相关资源
    最近更新 更多