左外加入 SQL Server 2014

Left Outer Join in SQL Server 2014

我们目前正在升级到 SQL Server 2014;我有一个在 SQL Server 2008 R2 中运行良好但 returns 在 SQL Server 2014 中重复的连接。问题似乎与谓词 AND L2.ACCOUNTING_PERIOD = RG.PERIOD_TO 有关,因为如果我更改它除了 4,我没有得到重复项。查询在 Accounting Period 4 中两次返回这些值。此查询获取所有先前会计期间的帐户余额,因此在本例中,它 returns 会计期间 0、1、2 和 3 的值正确,但随后复制了期间 4 的值。

SELECT
  A.ACCOUNT,
  SUM(A.POSTED_TRAN_AMT),
  SUM(A.POSTED_BASE_AMT),
  SUM(A.POSTED_TOTAL_AMT)
FROM
  PS_LEDGER A 
  LEFT JOIN PS_GL_ACCOUNT_TBL B  
    ON B.SETID = 'LTSHR'                    
  LEFT OUTER JOIN PS_LEDGER L2 
    ON A.BUSINESS_UNIT = L2.BUSINESS_UNIT
      AND A.LEDGER = L2.LEDGER
      AND A.ACCOUNT = L2.ACCOUNT                                    
      AND A.ALTACCT = L2.ALTACCT
      AND A.DEPTID = L2.DEPTID
      AND A.PROJECT_ID = L2.PROJECT_ID
      AND A.DATE_CODE = L2.DATE_CODE
      AND A.BOOK_CODE = L2.BOOK_CODE
      AND A.GL_ADJUST_TYPE = L2.GL_ADJUST_TYPE
      AND A.CURRENCY_CD = L2.CURRENCY_CD
      AND A.STATISTICS_CODE = L2.STATISTICS_CODE
      AND A.FISCAL_YEAR = L2.FISCAL_YEAR
      AND A.ACCOUNTING_PERIOD = L2.ACCOUNTING_PERIOD
      AND L2.ACCOUNTING_PERIOD = RG.PERIOD_TO
WHERE 
  A.BUSINESS_UNIT       = 'UK001'
  AND A.LEDGER          = 'LOCAL'
  AND A.FISCAL_YEAR     = 2015
  AND ( (A.ACCOUNTING_PERIOD BETWEEN 1 and 4
         AND B.ACCOUNT_TYPE IN ('E','R') )
                OR
        (A.ACCOUNTING_PERIOD BETWEEN 0 and  4
         AND B.ACCOUNT_TYPE IN ('A','L','Q') )   )
  AND A.STATISTICS_CODE = ' '
  AND A.ACCOUNT = '21101'
  AND A.CURRENCY_CD <> ' '
  AND A.CURRENCY_CD = 'GBP'
  AND B.SETID='LTSHR'
  AND B.ACCOUNT=A.ACCOUNT
  AND B.SETID = SETID
  AND B.EFFDT=(SELECT MAX(EFFDT) FROM PS_GL_ACCOUNT_TBL WHERE SETID='LTSHR'  AND  WHERE ACCOUNT=B.ACCOUNT AND EFFDT<='2015-01-31 00:00:00.000')
GROUP BY A.ACCOUNT
ORDER BY A.ACCOUNT

我倾向于怀疑您过于简化了原始查询以反映真正的问题,但我将根据到目前为止的评论回答所提出的问题。

由于您的查询实际上 select 没有从 table L2 派生的任何内容,也没有任何其他谓词依赖于 table 的任何内容,唯一的通过(左)连接完成它是复制预聚合结果的行,其中不止一个满足相同 L2 行的连接条件。这似乎不太可能是您想要的,尤其是那个特定的连接是 self 连接,所以我看不出有任何理由不完全删除它。 Dollars to doughnuts, 解决重复问题

我还建议删除 WHERE 子句中的相关子查询以支持加入内联视图,因为无论如何您已经加入子查询的基础 table。这个特定的内联视图使用 MAX() 的 window 函数版本而不是聚合函数版本。理想情况下,它会直接 select 只有具有目标 EFFDT 值的行,但如果不变得更复杂就不能这样做,这正是我试图避免的。因此,生成的查询像原始查询一样在外部过滤 EFFDT,但没有相关的子查询。

我还删除了一些冗余谓词并将其中一个比较混乱的谓词重写为更好的等价物。我以一种对我来说似乎更合乎逻辑的方式重新排列了谓词。

此外,由于您过滤的是 A.ACCOUNT 的特定值,因此 GROUP BYORDER_BY 该列没有意义(但没有错)。因此,我删除了这些子句以使查询更简单明了。

这是我想出的:

SELECT
  A.ACCOUNT,
  SUM(A.POSTED_TRAN_AMT),
  SUM(A.POSTED_BASE_AMT),
  SUM(A.POSTED_TOTAL_AMT)
FROM
  PS_LEDGER A 
  INNER JOIN (
      SELECT
        *,
        MAX(EFFDT) OVER (PARTITION BY ACCOUNT) AS MAX_EFFDT
      FROM PS_GL_ACCOUNT_TBL 
      WHERE
        EFFDT <= '2015-01-31 00:00:00.000'
        AND SETID = 'LTSHR'
    ) B  
    ON B.ACCOUNT=A.ACCOUNT
WHERE 
  A.ACCOUNT = '21101'
  AND A.BUSINESS_UNIT   = 'UK001'
  AND A.LEDGER          = 'LOCAL'
  AND A.FISCAL_YEAR     = 2015
  AND A.CURRENCY_CD = 'GBP'
  AND A.STATISTICS_CODE = ' '
  AND B.EFFDT = B.MAX_EFFDT
  AND CASE
      WHEN B.ACCOUNT_TYPE IN ('E','R')
        THEN A.ACCOUNTING_PERIOD BETWEEN 1 and 4
      WHEN B.ACCOUNT_TYPE IN ('A','L','Q')
        THEN A.ACCOUNTING_PERIOD BETWEEN 0 and 4
      ELSE 0
    END