子查询的“分组依据”问题

时间:2019-10-20 04:35:18

标签: mysql

我正在尝试进行汇总以显示统计信息,以按月显示收入与支出(表格中有日期和金额字段)。我在Oracle中通过以下查询多次执行此操作:

select X.ANIO, X.MES, (select sum(INGRESOS) from X)
from (
  select 
    YEAR(fecha) as ANIO, 
    MONTH(fecha) AS MES,
    format(sum(monto), 2) AS INGRESOS, 
    0 EGRESOS
  from in_out 
  where id_user = 0 
  and monto > 0 
  group by YEAR(fecha), MONTH(fecha) 

  union

  select 
    YEAR(fecha) as ANIO, 
    MONTH(fecha) AS MES,
    0,
    format(sum(monto), 2)
  from in_out 
  where id_user = 0 
  and monto < 0 
  group by YEAR(fecha), MONTH(fecha)
) X
group by X.ANIO, X.MES
order by 1 desc, 2 desc;

子查询(X表)获得了预期的结果,但顶部查询没有。

此查询有效(但需要更多时间)

select 
  YEAR(X.fecha) as ANIO, 
  MONTH(X.fecha) AS MES,
  (
    select format(sum(monto),2) 
    from in_out 
    where id_user=0 
    and monto > 0 
    and date_format(fecha,'%Y%m') = date_format(X.fecha,'%Y%m')
  ) AS INGRESOS,
  (
    select format(sum(monto),2) 
    from in_out 
    where id_user=0 
    and monto < 0 
    and date_format(fecha,'%Y%m') = date_format(X.fecha,'%Y%m')
  ) AS EGRESOS,
  (
    select format(sum(monto),2) 
    from in_out 
    where id_user=0 
    and date_format(fecha,'%Y%m') = date_format(X.fecha,'%Y%m')
  ) AS DELTA
from in_out X
group by YEAR(X.fecha), MONTH(X.fecha)
order by 1 desc, 2 desc;

我的疑问是为什么第一个查询不起作用。

2 个答案:

答案 0 :(得分:0)

执行虚拟表X(从X中选择sum(INGRESOS))时不存在,因此返回null。

您似乎想要按年份和月份进行输入操作

drop table if exists in_out;
create table in_out
(fecha date,monto int, id_user int);

insert into in_out values
('2019-01-01',10,0),
('2019-01-01',-20,0),
('2019-02-01',100,0),
('2019-02-01',-20,0);


select X.ANIO, X.MES, sum(INGRESOS)
from(
select YEAR(fecha) as ANIO, MONTH(fecha) AS MES,format(sum(monto),2) AS INGRESOS, 0 EGRESOS
from in_out where id_user=0 and monto > 0 group by YEAR(fecha), MONTH(fecha) 
union
select YEAR(fecha) as ANIO, MONTH(fecha) AS MES,0,format(sum(monto),2)
from in_out where id_user=0 and monto < 0 group by YEAR(fecha), MONTH(fecha)
) X
group by X.ANIO,X.MES
order by 1 desc, 2 desc;

+------+------+---------------+
| ANIO | MES  | sum(INGRESOS) |
+------+------+---------------+
| 2019 |    2 |           100 |
| 2019 |    1 |            10 |
+------+------+---------------+
2 rows in set (0.01 sec)

答案 1 :(得分:0)

这还应该为您提供所需的信息({ingresos / egresos,每月):

select 
  YEAR(fecha) as ANIO,
  MONTH(fecha) as MES,
  format(sum(CASE WHEN monto > 0 THEN monto END), 2) as INGRESOS, -- Sum of ingresos 
  format(sum(CASE WHEN monto < 0 THEN monto END), 2) as EGRESOS -- Sum of egresos
from in_out
where id_user = 0
group by YEAR(fecha), MONTH(fecha)
order by 1 desc, 2 desc
;

关于为什么原始查询的外部无效的原因,您想到的一件事是标量子查询:(select sum(INGRESOS) from X)。我认为它只会返回一个常量值,这是所有ingresos的总和,而与组无关。如果您看到所有月重复使用相同的值,那么这可能就是原因。

您的原始查询在多个级别中使用相同的GROUP BY。您可以使用我上面包含的查询来消除这种情况。

相关问题