我有以下简化的表结构:
CREATE TABLE CustTrans
(
CUSTACCOUNT VARCHAR(20),
JOURNALID BIGINT,
VALUE NUMERIC(28,12)
)
CREATE TABLE CustJour
(
ID BIGINT
)
以下查询(也简化):
DECLARE @LastJourId BIGINT
SELECT ct.CUSTACCOUNT ,
SUM(ct.VALUE + CASE WHEN @LastJourId != ct.JOURNALID THEN dbo.fnGetAdditionalCharges(ct.JOURNALID) ELSE 0 END)),
@LastJourId = ct.JOURNALID
FROM CustTrans AS ct
INNER JOIN CustJour AS cj ON cj.ID = ct.JOURNALID
GROUP BY ct.CUSTACCOUNT
ORDER BY ct.CUSTACCOUNT
这会显示错误消息:
A SELECT statement that assigns a value to a variable must not be combined with
data-retrieval operations.
函数fnGetAdditionalCharges
计算适用于期刊的额外费用。因此,每个期刊应该运行一次。
有没有办法在一个查询中计算日记帐的交易金额和额外费用?
在上面的示例中,我尝试使用局部变量来解决它,并将其分配给期刊ID的最后一个值,这就是试图知道日记帐行已更改的方式。
有很多类似的问题。最好的解决方案是对查询进行小的改动。我知道解决方案使用2个具有不同分组的SELECT语句 - 首先是CUSTACCOUNT和JOURNALID),然后是CUSTACCOUNT,并在该步骤上添加fnGetAdditionalCharges
值。
示例数据:
INSERT INTO CustJour ( ID ) VALUES (1);
INSERT INTO CustTrans ( CUSTACCOUNT, JOURNALID, VALUE ) VALUES ('1', 1, 1), ('1', 1, 1);
为简化起见,假设函数fnGetAdditionalCharges
每次返回1。在SELECT语句中,您可以使用1
在这种情况下,预期结果将是3. 2 - CustTran.VALUE
的总和以及1对现有期刊的费用。
可以有很多期刊。每个期刊可能包含许多交易。
答案 0 :(得分:1)
将查询分解为较小的部分并没有错;优化器会一直这样做,所以为什么我们不能呢?
如果我理解正确,你需要这样的东西:
with x as (
SELECT
ct.CUSTACCOUNT, ct.JOURNALID,
SUM(ct.VALUE) AS Value
FROM
CustTrans AS ct
INNER JOIN
CustJour AS cj ON cj.ID = ct.JOURNALID
GROUP BY ct.CUSTACCOUNT, ct.JOURNALID
)
select CustAccount, sum(Value + dbo.fnGetAdditionalCharges(x.JOURNALID))
from x
GROUP BY
x.CUSTACCOUNT
ORDER BY
x.CUSTACCOUNT
当然没有经过测试。像其他人说的那样,请给我们一些样本数据来验证它。
答案 1 :(得分:0)
您的问题是SELECT语句可以创建结果集,也可以分配给变量,但不能同时分配两个变量。 我建议将其分成多个部分;首先将CUSTACCOUNT,VALUE和JOURNALID选择到临时表中,然后根据临时表中的NZID值评估@LastJourId,并从临时表中重新选择并结合@LastJourId来获取最终结果集。
答案 2 :(得分:0)
SELECT CUSTACCOUNT, SUM(Value) + ISNULL(dbo.fnGetAdditionalCharges(journalid), 0) as Custaccvalue
FROM
(
SELECT distinct ct.CUSTACCOUNT, SUM(ct.VALUE) as Value, ct.JOURNALID as journalid
FROM
CustTrans AS ct
INNER JOIN
CustJour AS cj ON cj.ID = ct.JOURNALID
GROUP BY
ct.CUSTACCOUNT, ct.JOURNALID
) a
GROUP BY
CUSTACCOUNT
ORDER BY
CUSTACCOUNT