【问题标题】:SQL Union with CTE and Sum带有 CTE 和 Sum 的 SQL 联合
【发布时间】:2013-06-12 19:36:35
【问题描述】:

我完全是 SQL 新手,并且有两个查询到我想要的结果,但我认为我没有正确使用 UNION 来组合它们。我之前在这个网站上得到了一些帮助,其中有一部分是查询。 以下是我所拥有的缩短版本。

WITH RemoveData
     AS (SELECT a.PLANT_NO,
                a.ALLOC_WHDV_VOL,
                a.KW_CTR_REDELIVERED_HV,
                a.MTR_NO,
                a.MTR_SFX,
                a.TRNX_ID,
                a.REC_STATUS_CD,
                MAX(a.ACCT_DT) ACCT_DT
         FROM   GasStmt a
                INNER JOIN SettleSum c
                  ON a .= c.TRNX_ID
                     AND a.MTR_NO
                         ||a.MTR_SFX = c.MTR_NO
                                       ||c.MTR_SFX
                LEFT OUTER JOIN FuelsCat d
                  ON a.TRNX_ID = d.TRNX_ID
                     AND a.MTR_NO
                         ||a.MTR_SFX = d.MTR_NO
                                       ||d.MTR_SFX
         WHERE  a.REC_STATUS_CD = 'RR'
         GROUP  BY a.PLANT_NO,
                   a.ALLOC_WHDV_VOL,
                   a.KW_CTR_REDELIVERED_HV,
                   a.MTR_NO,
                   a.MTR_SFX,
                   a.TRNX_ID,
                   a.REC_STATUS_CD
         HAVING COUNT(a.REC_STATUS_CD) > 2) 
SELECT plant_no                   "PlantNumber",
       SUM(-a.ALLOC_WHDV_VOL)     "PlantStandardGrossWellheadMcf",
       SUM(KW_CTR_REDELIVERED_HV) "KeepWholeResidueMMBtu"
FROM   RemoveData a
GROUP  BY plant_no
UNION
SELECT a.PLANT_NO            "PlantNumber",
       SUM(a.ALLOC_WHDV_VOL) "PlantStandardGrossWellheadMcf",
       SUM(CASE
             WHEN a.REC_STATUS_CD = 'RR' THEN -a.KW_CTR_REDELIVERED_HV
             ELSE a.KW_CTR_REDELIVERED_HV
           END)              "KeepWholeResidueMMBtu"
FROM   GasStmt a
       INNER JOIN SettleSum c
         ON a.TRNX_ID = c.TRNX_ID
            AND a.MTR_NO
                ||a.MTR_SFX = c.MTR_NO
                              ||c.MTR_SFX
       LEFT OUTER JOIN FuelsCat d
         ON a.TRNX_ID = d.TRNX_ID
            AND a.MTR_NO
                ||a.MTR_SFX = d.MTR_NO
                              ||d.MTR_SFX
       LEFT OUTER JOIN (SELECT MTR_NO,
                               MTR_SFX,
                               TRNX_ID,
                               REC_STATUS_CD,
                               MAX(ACCT_DT) ACCT_DT
                        FROM   GasStmt
                        WHERE  REC_STATUS_CD = 'RR'
                        GROUP  BY MTR_NO,
                                  MTR_SFX,
                                  TRNX_ID,
                                  REC_STATUS_CD
                        HAVING COUNT(TRNX_ID) > 1) b
         ON a.MTR_NO = b.MTR_NO
            AND a.TRNX_ID = b.TRNX_ID
            AND a.Rec_Status_Cd = b.REC_STATUS_CD
            AND a.Acct_Dt = b.ACCT_DT
WHERE  TO_CHAR(a.PROD_DT, 'YYYY') >= TO_CHAR(ADD_MONTHS(SYSDATE, -36), 'YYYY')
       AND a.STATUS_UNIT_TM_CD = 'M'
       AND b.MTR_NO IS NULL
GROUP  BY a.PLANT_NO 

以上查询返回:

PlantNumber | PlantStandardGrossWellheadMcf    |KeepWholeResidueMMBtu
2           | 0                                | -3.96
2           | 80                               |  100
43          | 150                              |  0
133         | 75                               |  0

如果我单独使用 CTE 运行第一个查询,我会得到以下结果:

PlantNumber | PlantStandardGrossWellheadMcf  |KeepWholeResidueMMBtu
2           | 0                              |-3.96

自行运行第二个查询,这是我得到的示例数据示例:

PlantNumber | PlantStandardGrossWellheadMcf    |KeepWholeResidueMMBtu
2           | 80                               |  100
43          | 150                              |  0
133         | 75                               |  0

我的预期结果是根据植物编号组合数据。可以用 UNION 完成还是我做错了什么?这是我希望实现的目标:

PlantNumber | PlantStandardGrossWellheadMcf    |KeepWholeResidueMMBtu
2           | 80                               |  96.04
43          | 150                              |  0
133         | 75                               |  0

【问题讨论】:

  • 抱歉,我试着把它缩短一些并且把一些东西弄得更短。我稍微改了一下,希望它更易读。
  • 你最好把你的问题简化为尽可能短的例子。没有人愿意阅读所有内容。

标签: sql group-by sum union common-table-expression


【解决方案1】:

您可以将 UNION 语句的结果作为子查询执行聚合函数。根据您的特定 DBMS 可能会有一些变化,但是这个示例元代码应该解释这个概念:

SELECT "Results".ColA, "Results".SUM(ColB), "Results".SUM(ColC)
FROM (
      SELECT ColA, ColB, ColC
      FROM SomeTable1
      INNER JOIN SomeOtherTable1
      WHERE Criteria

      UNION

      SELECT ColA, ColB, ColC
      FROM SomeTable2
      INNER JOIN SomeOtherTable2
      WHERE Criteria
     ) "Results"

GROUP BY "Results".ColA

【讨论】:

  • 感谢您的回复。在查看以前用户的帖子后,我早些时候尝试过。当我尝试时:SELECT PLANT_NO, SUM(a.ALLOC_WHDV_VOL), SUM(KW_CTR_REDELIVERED_HV) FROM ( ...my above query... )GROUP BY PLANT_NO 它说 PLANT_NO 是无效标识符。如果我删除该组,则表示 KW_CTR_REDELIVERED_HV 是无效标识符。我错过了什么明显的东西吗?
  • 那么您可能需要指定别名。我编辑了我的回复,以显示整个 UNION 语句的别名为“Results”,每个 SELECT 和 GROUP BY 然后还指定“Results”项。您也可以尝试在 with 语句中定义 UNION,然后从中选择/分组:WITH (SELECT... UNION SELECT...) AS "Results" SELECT "Results".ColA, "Results".SUM(ColB), "Results".SUM(ColC) GROUP BY "Results".ColA
  • 再次感谢您的快速回复。似乎它必须是一个别名问题,但我一生都无法弄清楚。它要么说标识符无效,要么查询未正确结束。我已经尝试过GROUP BY Results.PLANT_NO"Results".PLANT_NO、`PlantNumber',以及我能想到的所有其他组合。我不知道如何引用子查询中的列。
  • 在上面的代码中,您在 Union 语句中将 PLANT_NO 别名为“PlantNumber”。如果这就是您的完整代码,您需要GROUP BY Results.PlantNumber,因为这是所述子查询返回的列名。
  • 这是一个非常复杂的语句,可能有更简单的方法可以实现您需要的结果,甚至可能不需要使用 UNION 或子查询。如果没有深入了解您的数据结构或业务需求,恐怕我没有想法。就个人而言,每当我最终陷入困境时,我都喜欢从头开始。有时,在做某件事很久之后,从头开始,您会发现以前没有想到的新的、不太复杂的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多