GROUP BY表达式必须至少包含... UNION查询

时间:2014-11-03 18:35:17

标签: sql-server oracle join union

我有一个大型查询实际上是一个视图,它在Oracle中有效,但在MS-SQL Server中没有。 UNION查询的后半部分故意具有硬编码值。

我发布了在Oracle 11g中运行的原始查询,但我尝试了另一种方法,它没有两个硬编码值为0,'财务'。该尝试发布在底部。

我收到的错误是:每个GROUP BY表达式必须包含至少一个不是外部引用的列。

   SELECT 
   RECOVERYTXNLEDGER.TXN_ID                AS TXN_ID,
   RECOVERYTXNLEDGER.REC_PROC_ID           AS RECORD_PROC_ID,
   RECOVERYPROCESS.REC_PROC_NAME           AS RECORD_PROC_NAME, 
   RECOVERYPROCESS.REC_PROC_TYPE_ID        AS RECORD_PROC_TYPE_ID,
   RECOVERYPROCTYPE.REC_PROC_TYPE_NAME     AS RECORD_PROC_TYPE_NAME,
   RECOVERYPROCESS.REC_PROC_SEQ            AS RECORD_PROC_SEQUENCE_NUM,
   RECOVERYTXNLEDGER.SVC_ID                AS SERVICE_ID,
   SERVICECATALOG.SVC_REF                  AS SERVICE_REFERENCE,
   SERVICECATALOG.SVC_DESC                 AS SERVICE_DESCRIPTION,
   SERVICECATALOG.SDG_ID                   AS SERVICE_STUDY_GROUP_ID,
   STUDYGROUP1.SDG_REF                     AS SERVICE_STUDY_GROUP_REF,
   STUDYGROUP1.SDG_DESC                    AS SERVICE_STUDY_GROUP_DESC,
   RECOVERYTXNLEDGER.SVC_PER_ID            AS SERVICE_PERIOD_ID,
   PERIOD1.PER_REF                         AS SERVICE_PERIOD_REFERENCE,
   PERIOD1.PER_DESC                        AS SERVICE_PERIOD_DESCRIPT,
   RECOVERYTXNLEDGER.SVC_SCN_ID            AS SERVICE_SCENARIO_ID,
   SCENARIO1.SCN_DESC                      AS SERVICE_SCENARIO_DESC,
   RECOVERYTXNLEDGER.SVC_RATE              AS SERVICE_RATE,
   RECOVERYTXNLEDGER.REC_TRANS_TYPE_ID     AS TRANS_TYPE_ID,
   RECOVERYTRANSTYPE.REC_TRANS_TYPE_NAME   AS TRANS_TYPE_NAME,
   RECOVERYTXNLEDGER.CUST_ACCT_REF         AS CUSToMER_ACCOUNT,
   RECOVERYTXNLEDGER.ORG_REF               AS ORGANIZATION_REFERENCE,
   ORGANIZATION.ORG_DESC                   AS ORGANIZATION_DESCRIPTION,
   STUDYGROUP.SDG_ID                       AS STUDY_GROUP_ID,                      
   STUDYGROUP.SDG_REF                      AS STUDY_GROUP_REFERENCE,
   STUDYGROUP.SDG_DESC                     AS STUDY_GROUP_DESCRIPT,
   SUM(RECOVERYTXNLEDGER.REC_AMT)          AS TRANSACTION_AMOUNT,
   RECOVERYTXNLEDGER.VOL_ID                AS VOLUME_ID,
   VOLUMECATALOG.VOL_REF                   AS VOLUME_REFERENCE,
   VOLUMECATALOG.VOL_DESC                  AS VOLUME_DESCRIPTION,
   RECOVERYTXNLEDGER.VOL_PER_ID            AS VOLUME_PERIOD_ID,
   PERIOD.PER_REF                          AS VOLUME_PERIOD_REFERENCE,
   PERIOD.PER_DESC                         AS VOLUME_PERIOD_DESCRIPT,
   RECOVERYTXNLEDGER.VOL_SCN_ID            AS VOLUME_SCENARIO_ID,
   SCENARIO.SCN_DESC                       AS VOLUME_SCENARIO_DESCRIPT,
   RECOVERYTXNLEDGER.VOL_QTY               AS VOLUME_QUANTITY
   FROM RECOVERYTXNLEDGER
   INNER JOIN SCENARIO SCENARIO1 ON RECOVERYTXNLEDGER.SVC_SCN_ID = SCENARIO1.SCN_ID
   INNER JOIN SERVICECATALOG ON RECOVERYTXNLEDGER.SVC_ID = SERVICECATALOG.SVC_ID
   INNER JOIN STUDYGROUP STUDYGROUP1 ON SERVICECATALOG.SDG_ID = STUDYGROUP1.SDG_ID
   INNER JOIN PERIOD PERIOD1 ON RECOVERYTXNLEDGER.SVC_PER_ID = PERIOD1.PER_ID
   INNER JOIN RECOVERYPROCESS ON RECOVERYTXNLEDGER.REC_PROC_ID = RECOVERYPROCESS.REC_PROC_ID
   INNER JOIN RECOVERYPROCTYPE ON RECOVERYPROCESS.REC_PROC_TYPE_ID = RECOVERYPROCTYPE.REC_PROC_TYPE_ID
   INNER JOIN ORGANIZATION ON RECOVERYTXNLEDGER.ORG_REF = ORGANIZATION.ORG_REF
   INNER JOIN STUDYGROUP ON ORGANIZATION.SDG_ID = STUDYGROUP.SDG_ID
   INNER JOIN RECOVERYTRANSTYPE ON RECOVERYTXNLEDGER.REC_TRANS_TYPE_ID = RECOVERYTRANSTYPE.REC_TRANS_TYPE_ID
   INNER JOIN VOLUMECATALOG ON RECOVERYTXNLEDGER.VOL_ID = VOLUMECATALOG.VOL_ID
   INNER JOIN PERIOD ON RECOVERYTXNLEDGER.VOL_PER_ID = PERIOD.PER_ID
   INNER JOIN SCENARIO ON RECOVERYTXNLEDGER.VOL_SCN_ID = SCENARIO.SCN_ID
   GROUP BY 
   RECOVERYTXNLEDGER.REC_PROC_ID,
   RECOVERYTXNLEDGER.TXN_ID,
   RECOVERYPROCESS.REC_PROC_NAME,
   RECOVERYPROCESS.REC_PROC_TYPE_ID,
   RECOVERYPROCTYPE.REC_PROC_TYPE_NAME,
   RECOVERYPROCESS.REC_PROC_SEQ,
   RECOVERYTXNLEDGER.SVC_ID,
   SERVICECATALOG.SVC_REF,
   SERVICECATALOG.SVC_DESC,
   SERVICECATALOG.SDG_ID,
   STUDYGROUP1.SDG_REF,
   STUDYGROUP1.SDG_DESC,
   RECOVERYTXNLEDGER.SVC_PER_ID,
   PERIOD1.PER_REF,
   PERIOD1.PER_DESC,
   RECOVERYTXNLEDGER.SVC_SCN_ID,
   SCENARIO1.SCN_DESC,
   RECOVERYTXNLEDGER.SVC_RATE,
   RECOVERYTXNLEDGER.REC_TRANS_TYPE_ID,
   RECOVERYTRANSTYPE.REC_TRANS_TYPE_NAME,
   RECOVERYTXNLEDGER.CUST_ACCT_REF,
   RECOVERYTXNLEDGER.ORG_REF,
   ORGANIZATION.ORG_DESC,
   STUDYGROUP.SDG_ID,
   STUDYGROUP.SDG_REF,
   STUDYGROUP.SDG_DESC,
   RECOVERYTXNLEDGER.VOL_ID,
   VOLUMECATALOG.VOL_REF,
   VOLUMECATALOG.VOL_DESC,
   RECOVERYTXNLEDGER.VOL_PER_ID,
   PERIOD.PER_REF,
   PERIOD.PER_DESC,
   RECOVERYTXNLEDGER.VOL_SCN_ID,
   SCENARIO.SCN_DESC,
   RECOVERYTXNLEDGER.VOL_QTY
   UNION
   SELECT 
   NULL                        AS TXN_ID,
   NULL                        AS REC_PROC_ID,
   NULL                        AS RECORD_PROC_NAME,
   NULL                        AS RECORD_PROC_TYPE_ID,
   NULL                        AS RECORD_PROC_TYPE_NAME,
   NULL                        AS RECORD_PROC_SEQUENCE_NUM,
   NULL                        AS SERVICE_ID,
   NULL                        AS SERVICE_REFERENCE,
   NULL                        AS SERVICE_DESCRIPTION,
   STUDYGROUP.SDG_ID           AS SERVICE_STUDY_GROUP_ID,
   STUDYGROUP.SDG_REF          AS SERVICE_STUDY_GROUP_REF,
   STUDYGROUP.SDG_DESC         AS SERVICE_STUDY_GROUP_DESC,
   NULL                        AS SERVICE_PERIOD_ID,
   NULL                        AS SERVICE_PERIOD_REFERENCE,
   NULL                        AS SERVICE_PERIOD_DESCRIPT,
   NULL                        AS SERVICE_SCENARIO_ID,
   NULL                        AS SERVICE_SCENARIO_DESC,
   NULL                        AS SERVICE_RATE,
   0                           AS TRANS_TYPE_ID, 
   'Financials'                AS TRANS_TYPE_NAME, 
   NULL                        AS CUSTOMER_ACCOUNT,
   Financials.ORG_REF          AS ORGANIZATION_REFERENCE, 
   Organization.ORG_DESC       AS ORGANIZATION_DESCRIPTION, 
   StudyGroup.SDG_ID           AS STUDY_GROUP_ID, 
   StudyGroup.SDG_REF          AS STUDY_GROUP_REFERENCE, 
   StudyGroup.SDG_DESC         AS STUDY_GROUP_DESCRIPT, 
   Sum(Financials.GL_AMOUNT)   AS TRANSACTION_AMOUNT, 
   Financials.FIN_ID           AS VOLUME_ID,
   FINANCIALS.GLACCT_REF       AS VOLUME_REFERENCE,
   FINANCIALS.GLACCT_DESC      AS VOLUME_DESCRIPTION,
   Financials.FIN_PER_ID       AS VOLUME_PERIOD_ID, 
   Period.PER_REF              AS VOLUME_PERIOD_REFERENCE, 
   Period.PER_DESC             AS VOLUME_PERIOD_DESCRIPT, 
   Financials.FIN_SCN_ID       AS VOLUME_SCENARIO_ID, 
   Scenario.SCN_DESC           AS VOLUME_SCENARIO_DESCRIPT,
   NULL                        AS VOLUME_QUANTITY
   FROM (((StudyGroup INNER JOIN Organization ON StudyGroup.SDG_ID = Organization.SDG_ID) 
   INNER JOIN Financials ON Organization.ORG_REF = Financials.ORG_REF) 
   INNER JOIN Scenario ON Financials.FIN_SCN_ID = Scenario.SCN_ID) 
   INNER JOIN Period ON Financials.FIN_PER_ID = Period.PER_ID
   GROUP BY 
   NULL,
   NULL,
   NULL,
   NULL,
   NULL,
   NULL,
   NULL,
   NULL,
   NULL,
   STUDYGROUP.SDG_ID,
   STUDYGROUP.SDG_REF,
   STUDYGROUP.SDG_DESC,
   NULL,
   NULL,
   NULL,
   NULL,
   NULL,
   NULL,
   0,
   'Financials',
   NULL,
   FINANCIALS.ORG_REF,
   ORGANIZATION.ORG_DESC,
   STUDYGROUP.SDG_ID,
   STUDYGROUP.SDG_REF,
   STUDYGROUP.SDG_DESC,
   FINANCIALS.FIN_ID,
   FINANCIALS.GLACCT_REF,
   FINANCIALS.GLACCT_DESC,
   FINANCIALS.FIN_PER_ID,
   PERIOD.PER_REF,
   PERIOD.PER_DESC,
   FINANCIALS.FIN_SCN_ID,
   SCENARIO.SCN_DESC,
   NULL

我确实尝试用以下内容替换这两个文字:

CASE WHEN StudyGroup.SDG_ID >= 0 THEN 0 ELSE 0 END AS TRANS_TYPE_ID, 
CASE WHEN StudyGroup.SDG_ID >= 0 THEN 'Financials' ELSE 'Financials' END AS TRANS_TYPE_NAME, 

并在GROUP BY:

CASE WHEN StudyGroup.SDG_ID >= 0 THEN 0 ELSE 0 END,
CASE WHEN StudyGroup.SDG_ID >= 0 THEN 'Financials' ELSE 'Financials' END,

...谢谢

1 个答案:

答案 0 :(得分:0)

我建议使用表别名,特别是对于像这样的较大查询。这使得阅读它变得容易得多。我稍微调整了你的第二个查询并添加了一些别名。然后我意识到你在查询中有两个相同的3列,你被他们多次分组。这不会影响结果,但会有点混乱。我猜这个问题出现在你的第二个查询中,所以在你将它添加到UNION之前,我会将其隔离并使其正常工作。

SELECT 
   NULL                        AS TXN_ID,
   NULL                        AS REC_PROC_ID,
   NULL                        AS RECORD_PROC_NAME,
   NULL                        AS RECORD_PROC_TYPE_ID,
   NULL                        AS RECORD_PROC_TYPE_NAME,
   NULL                        AS RECORD_PROC_SEQUENCE_NUM,
   NULL                        AS SERVICE_ID,
   NULL                        AS SERVICE_REFERENCE,
   NULL                        AS SERVICE_DESCRIPTION,
   sg.SDG_ID           AS SERVICE_STUDY_GROUP_ID,
   sg.SDG_REF          AS SERVICE_STUDY_GROUP_REF,
   sg.SDG_DESC         AS SERVICE_STUDY_GROUP_DESC,
   NULL                        AS SERVICE_PERIOD_ID,
   NULL                        AS SERVICE_PERIOD_REFERENCE,
   NULL                        AS SERVICE_PERIOD_DESCRIPT,
   NULL                        AS SERVICE_SCENARIO_ID,
   NULL                        AS SERVICE_SCENARIO_DESC,
   NULL                        AS SERVICE_RATE,
   0                           AS TRANS_TYPE_ID, 
   'Financials'                AS TRANS_TYPE_NAME, 
   NULL                        AS CUSTOMER_ACCOUNT,
   f.ORG_REF          AS ORGANIZATION_REFERENCE, 
   o.ORG_DESC       AS ORGANIZATION_DESCRIPTION, 
   sg.SDG_ID           AS STUDY_GROUP_ID, 
   sg.SDG_REF          AS STUDY_GROUP_REFERENCE, 
   sg.SDG_DESC         AS STUDY_GROUP_DESCRIPT, 
   Sum(f.GL_AMOUNT)   AS TRANSACTION_AMOUNT, 
   f.FIN_ID           AS VOLUME_ID,
   f.GLACCT_REF       AS VOLUME_REFERENCE,
   f.GLACCT_DESC      AS VOLUME_DESCRIPTION,
   f.FIN_PER_ID       AS VOLUME_PERIOD_ID, 
   p.PER_REF              AS VOLUME_PERIOD_REFERENCE, 
   p.PER_DESC             AS VOLUME_PERIOD_DESCRIPT, 
   f.FIN_SCN_ID       AS VOLUME_SCENARIO_ID, 
   s.SCN_DESC           AS VOLUME_SCENARIO_DESCRIPT,
   NULL                        AS VOLUME_QUANTITY
   FROM StudyGroup sg 
   INNER JOIN Organization o ON sg.SDG_ID = o.SDG_ID
   INNER JOIN Financials f ON o.ORG_REF = f.ORG_REF
   INNER JOIN Scenario s ON f.FIN_SCN_ID = s.SCN_ID
   INNER JOIN Period p ON f.FIN_PER_ID = p.PER_ID
   GROUP BY 
   sg.SDG_ID,
   sg.SDG_REF,
   sg.SDG_DESC,
   f.ORG_REF,
   o.ORG_DESC,
   f.FIN_ID,
   f.GLACCT_REF,
   f.GLACCT_DESC,
   f.FIN_PER_ID,
   p.PER_REF,
   p.PER_DESC,
   f.FIN_SCN_ID,
   s.SCN_DESC

另外,我不确定您是否正在使用UNION,因为您想要消除两个查询之间的重复。如果没有,你将通过使用UNION ALL获得更好的性能,因此它不必检查重复项。