SQL Server 2008:运行 总计和空记录
SQL Server 2008 : running totals and null records
我有几个查询可以从我们的 ERP 中获取帐户余额,但是我正在尝试解决几个问题,我很好奇是否有更好的方法或者 SQL 服务器的更新版本是否有功能来解决这些问题中的任何一个。
我们的 ERP 仅在 activity 与帐户关联的期间生成余额记录。 ERP 应用程序和报告按期间汇总值,但没有记录添加到数据库中,因此需要按期间平衡的自定义流程需要 query/view 来计算此信息。
我的解决方法是使用一个全局变量故意从 Account
table 和我创建的伪句点 table 创建副本,见下文
我们的帐户周期 table 不包含周期索引(我想它应该是行 ID 但是在某些时候错误地添加了会计周期并且索引被丢弃了订单。ERP 提供商建议我在没有完全重新实施的情况下不要更新它)。我为此创建了一个解决方法 table。
所以我有几个解决这些问题的查询,但它们 运行 只用少数几个账户很慢,所以一个完整的伪 table 账户余额至少在我的方法中不实用.
我在下面提供了一个示例,用于计算未按年度汇总到留存收益(资产、负债、权益)的账户的期间余额
SELECT
ID AS ACCOUNT_ID, ind.Month_Index, ind.Period,
(SELECT
ISNULL(SUM(CASE WHEN A3.TYPE IN ('e','r') THEN NULL
WHEN A3.TYPE = 'a' THEN ISNULL(AB3.DEBIT_AMOUNT, 0) - ISNULL(AB3.CREDIT_AMOUNT, 0)
ELSE ISNULL(AB3.CREDIT_AMOUNT, 0) - ISNULL(AB3.DEBIT_AMOUNT, 0) END), 0)
FROM ACCOUNT_BALANCE AS AB3
LEFT OUTER JOIN ACCOUNT AS A3 ON AB3.ACCOUNT_ID = A3.ID
LEFT OUTER JOIN
(SELECT YEAR, Month_Num, Month_Index, Period
FROM UFC_Calander
GROUP BY YEAR, Month_Num, Month_Index, Period) AS ind2 ON AB3.ACCT_YEAR = ind2.YEAR AND AB3.ACCT_PERIOD = ind2.Month_Num
WHERE A.ID = AB3.ACCOUNT_ID
AND A3.CURRENCY_ID = '(USA) $'
AND ind2.Month_Index <= ind.Month_Index) AS BALANCE_AQL
FROM
ACCOUNT AS A
LEFT OUTER JOIN
ACCOUNT_PERIOD AS per ON 'UCC' = per.SITE_ID
LEFT OUTER JOIN
ACCOUNT_BALANCE AS AB ON A.ID = AB.ACCOUNT_ID
AND per.ACCT_YEAR = AB.ACCT_YEAR
AND per.ACCT_PERIOD = AB.ACCT_PERIOD
AND AB.CURRENCY_ID = '(USA) $'
LEFT OUTER JOIN
(SELECT YEAR, Month_Num, Month_Index, Period
FROM UFC_Calander
GROUP BY YEAR, Month_Num, Month_Index, Period) AS ind ON per.ACCT_YEAR = ind.YEAR AND per.ACCT_PERIOD = ind.Month_Num
WHERE
ID IN ('120-1140-0000', '120-1190-1190', '120-1190-1193',
'120-1190-1194', '210-2100-0000', '210-2101-0000')
GROUP BY
ID, ind.Month_Index, ind.Period
ORDER BY
ind.Month_Index DESC, ACCOUNT_ID DESC
任何可能提高此查询性能的建议都将不胜感激。
我的高级建议如下:
避免使用 IN 子句。如果可能(假设帐户 table 不是太大,只为您需要的列创建一个临时 table 并使用您正在使用的 ID 加载该数据。)然后在您的代码中使用它以上.
(不是性能问题,而是更多的细微变化)。 ISNULL(SUM... 部分只需要因为你有一个 "A3.TYPE IN ('e', 'r') THEN NULL"。如果你说 THEN 0,你可以避免空检查。
select 中的相关子查询没问题,但它是一个多部分连接,很可能会导致速度变慢。对于如何将其分解为两个独立的逻辑数据抓取然后重新组合在一起,我不确定 100% 有信心,但这是我在这里看到的最好的结果。
我有几个查询可以从我们的 ERP 中获取帐户余额,但是我正在尝试解决几个问题,我很好奇是否有更好的方法或者 SQL 服务器的更新版本是否有功能来解决这些问题中的任何一个。
我们的 ERP 仅在 activity 与帐户关联的期间生成余额记录。 ERP 应用程序和报告按期间汇总值,但没有记录添加到数据库中,因此需要按期间平衡的自定义流程需要 query/view 来计算此信息。
我的解决方法是使用一个全局变量故意从
Account
table 和我创建的伪句点 table 创建副本,见下文我们的帐户周期 table 不包含周期索引(我想它应该是行 ID 但是在某些时候错误地添加了会计周期并且索引被丢弃了订单。ERP 提供商建议我在没有完全重新实施的情况下不要更新它)。我为此创建了一个解决方法 table。
所以我有几个解决这些问题的查询,但它们 运行 只用少数几个账户很慢,所以一个完整的伪 table 账户余额至少在我的方法中不实用.
我在下面提供了一个示例,用于计算未按年度汇总到留存收益(资产、负债、权益)的账户的期间余额
SELECT
ID AS ACCOUNT_ID, ind.Month_Index, ind.Period,
(SELECT
ISNULL(SUM(CASE WHEN A3.TYPE IN ('e','r') THEN NULL
WHEN A3.TYPE = 'a' THEN ISNULL(AB3.DEBIT_AMOUNT, 0) - ISNULL(AB3.CREDIT_AMOUNT, 0)
ELSE ISNULL(AB3.CREDIT_AMOUNT, 0) - ISNULL(AB3.DEBIT_AMOUNT, 0) END), 0)
FROM ACCOUNT_BALANCE AS AB3
LEFT OUTER JOIN ACCOUNT AS A3 ON AB3.ACCOUNT_ID = A3.ID
LEFT OUTER JOIN
(SELECT YEAR, Month_Num, Month_Index, Period
FROM UFC_Calander
GROUP BY YEAR, Month_Num, Month_Index, Period) AS ind2 ON AB3.ACCT_YEAR = ind2.YEAR AND AB3.ACCT_PERIOD = ind2.Month_Num
WHERE A.ID = AB3.ACCOUNT_ID
AND A3.CURRENCY_ID = '(USA) $'
AND ind2.Month_Index <= ind.Month_Index) AS BALANCE_AQL
FROM
ACCOUNT AS A
LEFT OUTER JOIN
ACCOUNT_PERIOD AS per ON 'UCC' = per.SITE_ID
LEFT OUTER JOIN
ACCOUNT_BALANCE AS AB ON A.ID = AB.ACCOUNT_ID
AND per.ACCT_YEAR = AB.ACCT_YEAR
AND per.ACCT_PERIOD = AB.ACCT_PERIOD
AND AB.CURRENCY_ID = '(USA) $'
LEFT OUTER JOIN
(SELECT YEAR, Month_Num, Month_Index, Period
FROM UFC_Calander
GROUP BY YEAR, Month_Num, Month_Index, Period) AS ind ON per.ACCT_YEAR = ind.YEAR AND per.ACCT_PERIOD = ind.Month_Num
WHERE
ID IN ('120-1140-0000', '120-1190-1190', '120-1190-1193',
'120-1190-1194', '210-2100-0000', '210-2101-0000')
GROUP BY
ID, ind.Month_Index, ind.Period
ORDER BY
ind.Month_Index DESC, ACCOUNT_ID DESC
任何可能提高此查询性能的建议都将不胜感激。
我的高级建议如下:
避免使用 IN 子句。如果可能(假设帐户 table 不是太大,只为您需要的列创建一个临时 table 并使用您正在使用的 ID 加载该数据。)然后在您的代码中使用它以上.
(不是性能问题,而是更多的细微变化)。 ISNULL(SUM... 部分只需要因为你有一个 "A3.TYPE IN ('e', 'r') THEN NULL"。如果你说 THEN 0,你可以避免空检查。
select 中的相关子查询没问题,但它是一个多部分连接,很可能会导致速度变慢。对于如何将其分解为两个独立的逻辑数据抓取然后重新组合在一起,我不确定 100% 有信心,但这是我在这里看到的最好的结果。