group by并选择max with value null

时间:2017-06-03 15:21:38

标签: sql oracle

我的查询有下一个问题

SELECT 
T.DETALLE_BECA_ANIO anio,
T.DETALLE_BECA_MES mes,
T.DETALLE_BECA_NIVEL_EDU_ID edu_id,
T.DETALLE_BECA_TRAMO_ID tr_id,

MAX(
CASE
  WHEN T.DETALLE_BECA_TIPO_BENE_ID IS NULL
  THEN NVL(DETALLE_BECA_VALOR,0)
  ELSE 0
END) mant ,
MAX(
  CASE
  WHEN T.DETALLE_BECA_TIPO_BENE_ID = 1
  THEN NVL(DETALLE_BECA_VALOR,0)
  ELSE 0
  END) tras
  FROM
(SELECT DETALLE_BECA_NIVEL_EDU_ID,
  DETALLE_BECA_BECA_ID,
  DETALLE_BECA_TIPO_BENE_ID,
  DETALLE_BECA_VALOR,
  DETALLE_BECA_MES,
  DETALLE_BECA_REGION_ID,
  DETALLE_BECA_PROVINCIA_ID,
  DETALLE_BECA_ANIO,
  DETALLE_BECA_TRAMO_ID,
  DETALLE_BECA_COMUNA_ID
FROM TBL_DETALLE_BECAS

WHERE (DETALLE_BECA_TIPO_BENE_ID = 1
OR DETALLE_BECA_TIPO_BENE_ID   IS NULL)
and DETALLE_BECA_BECA_ID = 1
and detalle_beca_mes = 3
) T
GROUP BY T.DETALLE_BECA_BECA_ID,
T.DETALLE_BECA_TRAMO_ID,
T.DETALLE_BECA_REGION_ID,
T.DETALLE_BECA_PROVINCIA_ID,
T.DETALLE_BECA_ANIO,
T.DETALLE_BECA_MES,
T.DETALLE_BECA_NIVEL_EDU_ID,
T.DETALLE_BECA_COMUNA_ID
ORDER BY T.DETALLE_BECA_BECA_ID,
T.DETALLE_BECA_MES,
T.DETALLE_BECA_NIVEL_EDU_ID

输出:

  "ANIO"    "MES"   "EDU_ID"    "TR_ID" "MANT"  "TRAS"
    2017      3         2        0.62     0      NULL
    2017      3         3        1.24     6      NULL 
    2017      3        NULL       1.0     NULL     1

我需要在TR_ID中值为2,3的EDU_ID为空的和值,并且在“tras”中将值替换为来自EDU的值为null

   "ANIO"   "MES"   "EDU_ID"    "TR_ID" "MANT"  "TRAS"
    2017      3         2        1.62     0      1
    2017      3         3        2.24     6      1 

我用min(edu_id)或max(edu_id)来查询但是无法解决我的问题。

我遇到的另一件事是使用同一个表进行连接

1 个答案:

答案 0 :(得分:0)

首先,这对您的查询更有意义:

SELECT T.DETALLE_BECA_ANIO as anio, T.DETALLE_BECA_MES as mes,
       T.DETALLE_BECA_NIVEL_EDU_ID as edu_id, T.DETALLE_BECA_TRAMO_ID as tr_id,
       MAX(CASE WHEN T.DETALLE_BECA_TIPO_BENE_ID IS NULL
                THEN NVL(DETALLE_BECA_VALOR, 0)
                ELSE 0
           END) as mant ,
       MAX(CASE WHEN T.DETALLE_BECA_TIPO_BENE_ID = 1
                THEN NVL(DETALLE_BECA_VALOR,0)
                ELSE 0
           END) tras
FROM TBL_DETALLE_BECAS
WHERE (DETALLE_BECA_TIPO_BENE_ID = 1 OR DETALLE_BECA_TIPO_BENE_ID IS NULL) AND
      DETALLE_BECA_BECA_ID = 1 AND
      detalle_beca_mes = 3
GROUP BY T.DETALLE_BECA_ANIO, T.DETALLE_BECA_MES,
         T.DETALLE_BECA_NIVEL_EDU_ID, T.DETALLE_BECA_TRAMO_ID
ORDER BY T.DETALLE_BECA_BECA_ID, T.DETALLE_BECA_MES, T.DETALLE_BECA_NIVEL_EDU_ID;

这消除了子查询(不必要的),并且只返回被返回的列的聚合。正确的查询可能会解决您的问题。

但是,您似乎希望使用NULL成为"所有"对于其他列。如果是这样的话,这样的话会起作用:

WITH t as (
      SELECT T.DETALLE_BECA_ANIO as anio, T.DETALLE_BECA_MES as mes,
             T.DETALLE_BECA_NIVEL_EDU_ID as edu_id, T.DETALLE_BECA_TRAMO_ID as tr_id,
             MAX(CASE WHEN T.DETALLE_BECA_TIPO_BENE_ID IS NULL
                      THEN NVL(DETALLE_BECA_VALOR, 0)
                      ELSE 0
                 END) as mant ,
             MAX(CASE WHEN T.DETALLE_BECA_TIPO_BENE_ID = 1
                      THEN NVL(DETALLE_BECA_VALOR,0)
                      ELSE 0
                 END) tras
      FROM TBL_DETALLE_BECAS
      WHERE (DETALLE_BECA_TIPO_BENE_ID = 1 OR DETALLE_BECA_TIPO_BENE_ID IS NULL) AND
            DETALLE_BECA_BECA_ID = 1 AND
            detalle_beca_mes = 3
      GROUP BY T.DETALLE_BECA_ANIO, T.DETALLE_BECA_MES,
             T.DETALLE_BECA_NIVEL_EDU_ID, T.DETALLE_BECA_TRAMO_ID
     )
SELECT t.ANIO, t.MES, t.EDU_ID,
       COALESCE(t.TR_ID, 0) + COALESCE(tnull.TR_ID, 0) as TR_ID,
       t.MANT,
       COALESCE(t.TRAS, 0) + COALESCE(tnull.TRAS, 0) as TRAS
FROM t LEFT JOIN
     (SELECT t.*
      FROM t
      WHERE t.edu_id IS NULL
     ) tnull
     ON tnull.ANIO = t.ANIO AND tnull.MES = t.MES
WHERE t.edu_id IS NOT NULL
ORDER BY T.DETALLE_BECA_BECA_ID, T.DETALLE_BECA_MES, T.DETALLE_BECA_NIVEL_EDU_ID;