我对SQL查询还比较陌生,而Stack Overflow以前通过阅读其他人的问题或回答我的特定问题为我指明了正确的方向。但是我找不到能解决我问题的任何东西。
我有两个数据表,它们已结合在一起以创建属于特定帐户的交易列表。我已经完成并工作了这一部分(可能不是最有效的编码,但据我所知)。如果需要,我可以发布代码。结果如下所示,“余额”列是在SQL查询中计算的,并且不在任何表中:
这很好,但是我想在开始时添加一个“期初余额”行,该行将对特定日期之前该帐户中的所有记录求和,余额中将包括期初金额。我希望它看起来像这样:
我使用的调整后代码:
SELECT
Result.TransID,
Result.TransDate,
Result.Reference,
Result.Description,
Result.Amount,
SUM(Result.Amount) OVER(PARTITION BY Result.ledgerRef ORDER BY
Result.TransID) AS 'Balance'
FROM
(
(SELECT
-1 TransID,
NULL AS 'TransDate',
NULL AS 'Reference',
OB.Description,
SUM(OB.Amount) AS 'Amount',
SUM(OB.Amount) AS 'Balance',
OB.LedgerRef
FROM
(
(SELECT
-1 AS 'ID',
MAX(T.dtm_TransDate) AS 'TransDate',
' ' AS 'Reference',
'Opening Balance' AS 'Description',
SUM(CASE
WHEN LT.txt_LedgerTypeRef = 'REV' then -TD.dbl_TransDataAmount
WHEN LT.txt_LedgerTypeRef = 'EXP' then TD.dbl_TransDataAmount
WHEN LT.txt_LedgerTypeRef = 'ASS' then TD.dbl_TransDataAmount
WHEN LT.txt_LedgerTypeRef = 'LIA' then -TD.dbl_TransDataAmount
WHEN LT.txt_LedgerTypeRef = 'EQU' then -TD.dbl_TransDataAmount
ELSE TD.dbl_TransDataAmount
END) AS 'Amount',
LT.txt_LedgerTypeRef AS 'LedgerRef'
FROM dbo.tbl_TransData AS TD
JOIN dbo.tbl_Trans AS T ON T.int_Trans_ID = TD.int_TransID
JOIN dbo.tbl_TransType AS TT ON TT.int_TransType_ID = T.int_TransTypeID
JOIN dbo.tbl_Account AS A ON A.int_Account_ID = TD.int_AccountID
JOIN dbo.tbl_Ledger AS L ON L.int_Ledger_ID = A.int_LedgerID
JOIN dbo.tbl_LedgerType AS LT ON LT.int_LedgerType_ID = L.int_LedgerTypeID
WHERE
T.int_BusinessID = 1
AND T.bit_Archive <> 1
AND T.bit_Disabled <> 1
AND T.bit_TransDelete <> 1
AND T.dtm_TransDate < '2019-01-01'
AND TD.int_AccountID = 2167
GROUP BY
LT.txt_LedgerTypeRef,
TD.dbl_TransDataAmount
)
UNION
(SELECT
-1 AS 'ID',
MAX(T.dtm_TransDate) AS 'TransDate',
' ' AS 'Reference',
'Opening Balance' AS 'Description',
SUM(CASE
WHEN LT.txt_LedgerTypeRef = 'REV' THEN -T.dbl_TransAmount
WHEN LT.txt_LedgerTypeRef = 'EXP' THEN T.dbl_TransAmount
WHEN LT.txt_LedgerTypeRef = 'ASS' THEN T.dbl_TransAmount
WHEN LT.txt_LedgerTypeRef = 'LIA' THEN -T.dbl_TransAmount
WHEN LT.txt_LedgerTypeRef = 'EQU' THEN -T.dbl_TransAmount
ELSE T.dbl_TransAmount
END) AS 'Amount',
LT.txt_LedgerTypeRef AS 'LedgerRef'
FROM dbo.tbl_Trans AS T
JOIN dbo.tbl_TransType AS TT ON TT.int_TransType_ID = T.int_TransTypeID
JOIN dbo.tbl_Account AS A ON A.int_Account_ID = T.int_AccountIDBank
JOIN dbo.tbl_Ledger AS L ON L.int_Ledger_ID = A.int_LedgerID
JOIN dbo.tbl_LedgerType AS LT ON LT.int_LedgerType_ID = L.int_LedgerTypeID
WHERE
T.int_BusinessID = 1
AND T.bit_Archive <> 1
AND T.bit_Disabled <> 1
AND T.bit_TransDelete <> 1
AND T.dtm_TransDate < '2019-01-01'
AND T.int_AccountIDBank = 2167
GROUP BY
LT.txt_LedgerTypeRef,
T.dbl_TransAmount
)
) AS OB
GROUP BY
OB.Description,
OB.LedgerRef
)
UNION
(SELECT
TR.TransID,
TR.TransDate,
TR.Reference,
TR.Description,
TR.Amount,
SUM(TR.amount) OVER(PARTITION BY TR.ledgerRef ORDER BY TR.TransID) AS 'Balance',
TR.LedgerRef
FROM
(
(SELECT
T.int_Trans_ID AS 'TransID',
T.dtm_TransDate AS 'TransDate',
concat(TT.txt_TransTypeCode, T.dbl_TransRef) AS 'Reference',
TD.txt_TransDataDescription AS 'Description',
CASE
WHEN LT.txt_LedgerTypeRef = 'REV' then -TD.dbl_TransDataAmount
WHEN LT.txt_LedgerTypeRef = 'EXP' then TD.dbl_TransDataAmount
WHEN LT.txt_LedgerTypeRef = 'ASS' then TD.dbl_TransDataAmount
WHEN LT.txt_LedgerTypeRef = 'LIA' then -TD.dbl_TransDataAmount
WHEN LT.txt_LedgerTypeRef = 'EQU' then -TD.dbl_TransDataAmount
ELSE TD.dbl_TransDataAmount
END AS 'Amount',
LT.txt_LedgerTypeRef AS 'LedgerRef'
FROM dbo.tbl_TransData AS TD
JOIN dbo.tbl_Trans AS T ON T.int_Trans_ID = TD.int_TransID
JOIN dbo.tbl_TransType AS TT ON TT.int_TransType_ID = T.int_TransTypeID
JOIN dbo.tbl_Account AS A ON A.int_Account_ID = TD.int_AccountID
JOIN dbo.tbl_Ledger AS L ON L.int_Ledger_ID = A.int_LedgerID
JOIN dbo.tbl_LedgerType AS LT ON LT.int_LedgerType_ID = L.int_LedgerTypeID
WHERE
T.int_BusinessID = 1
AND T.bit_Archive <> 1
AND T.bit_Disabled <> 1
AND T.bit_TransDelete <> 1
AND T.dtm_TransDate >= '2019-01-01'
AND TD.int_AccountID = 2167
)
UNION
(SELECT
T.int_Trans_ID AS 'TransID',
T.dtm_TransDate AS 'TransDate',
concat(TT.txt_TransTypeCode, T.dbl_TransRef) AS 'Reference',
T.txt_TransDescription AS 'Description',
CASE
WHEN LT.txt_LedgerTypeRef = 'REV' THEN -T.dbl_TransAmount
WHEN LT.txt_LedgerTypeRef = 'EXP' THEN T.dbl_TransAmount
WHEN LT.txt_LedgerTypeRef = 'ASS' THEN T.dbl_TransAmount
WHEN LT.txt_LedgerTypeRef = 'LIA' THEN -T.dbl_TransAmount
WHEN LT.txt_LedgerTypeRef = 'EQU' THEN -T.dbl_TransAmount
ELSE T.dbl_TransAmount
END AS 'Amount',
LT.txt_LedgerTypeRef AS 'LedgerRef'
FROM dbo.tbl_Trans AS T
JOIN dbo.tbl_TransType AS TT ON TT.int_TransType_ID = T.int_TransTypeID
JOIN dbo.tbl_Account AS A ON A.int_Account_ID = T.int_AccountIDBank
JOIN dbo.tbl_Ledger AS L ON L.int_Ledger_ID = A.int_LedgerID
JOIN dbo.tbl_LedgerType AS LT ON LT.int_LedgerType_ID = L.int_LedgerTypeID
WHERE
T.int_BusinessID = 1
AND T.bit_Archive <> 1
AND T.bit_Disabled <> 1
AND T.bit_TransDelete <> 1
AND T.dtm_TransDate >= '2019-01-01'
AND T.int_AccountIDBank = 2167
)
) AS TR
)
) AS Result
这一切似乎都正常,在这里我不得不合并两个表以用于期初余额和交易,所以那里有很多联合。
结果如下:
仅一点,在期初余额行上,我希望“金额”为空白,但是如果我将其保留在期初余额查询之外,则结转的余额是错误的。它在代码的第17行。不确定是否可以做到。
再一次提出任何建议将不胜感激。
答案 0 :(得分:1)
在没有所有表格并进行完整设置和样本填充的情况下,我可以提供以下信息...
您的INNER查询将所有交易和明细预先收集起来,然后合并为一组...,然后由外部查询将它们汇总。
我会再添加一个调整查询的方法(同样,只是指导与全部数据准备等)。
select
… original fields and sum(…)( over/order by)
from
( InnerQuery1
UNION
InnerQuery2 )
并更改为
select
… original fields and sum(…)( over/order by)
from
( InnerQuery1
where TransDate > YourCutoffDate
UNION
InnerQuery2
where TransDate > YourCutoffDate
UNION
( select
-- place-holder field to match the union requirements
-1 int_Trans_ID,
MAX( ExistingDataDate ) AS 'TransDate',
' ' as 'Reference',
'Balance Forward' as 'Description',
SUM( CASE
WHEN LT.txt_LedgerTypeRef = 'REV' THEN -T.dbl_TransAmount
WHEN LT.txt_LedgerTypeRef = 'EXP' THEN T.dbl_TransAmount
WHEN LT.txt_LedgerTypeRef = 'ASS' THEN T.dbl_TransAmount
WHEN LT.txt_LedgerTypeRef = 'LIA' THEN -T.dbl_TransAmount
WHEN LT.txt_LedgerTypeRef = 'EQU' THEN -T.dbl_TransAmount
ELSE T.dbl_TransAmount
END ) AS 'Amount',
LT.txt_LedgerTypeRef AS 'LedgerRef'
from
. . .
where
TransDate <= YourCutoffDate
group by
?LedgerReg -- unsure per your data sources
)
)
在这种情况下,您始终可以根据自己的优点运行新查询以实现余额平衡,以确保使语法和聚合意义成为您想要获取的意图。通过使用WHERE子句将顶部查询限制为仅包含截止日期之后的那些,它们将是它们自己的。对于截止之前的所有交易,此新查询将预汇总到单个行(每个分类帐)中,仅留下1条记录(每个分类帐)。在交易日期使用MAX()可以确保它浮动到按日期排列的顶部,并且应该首先使用它来启动余额远期价值。
希望这很有意义,因为其余的查询已经在起作用。在这里,您实质上是在查询截止日期之前或之前的所有记录并添加到列表中。因此,请先自行构建此查询,然后调整您现有的查询以包含为其他联合。
最后清除期初余额。您具有ID = -1的受控值。使用案例/何时删除。在您的OUTERMOST查询中,更改
修订以清除期初余额金额行...
Result.Amount,
SUM(Result.Amount) OVER(PARTITION BY Result.ledgerRef ORDER BY
到
case when int_trans_id < 0 then 0 else Result.Amount end Amount,
SUM(Result.Amount) OVER(PARTITION BY Result.ledgerRef ORDER BY
答案 1 :(得分:0)
正如我在评论中提到的那样,当您包含代码时,这要容易得多,因此我们可以对其进行添加。无论如何,这是相似的随机表的答案:
SELECT SUM(T.[Value]) AS OPENING_BALANCE --Sum (addition of) all values in col [Value]
FROM
(SELECT [Id]
,[Title]
,[Units]
,[Value]
FROM [DBNAME].[dbo].[Data]) T