SUM()仅取一行

时间:2018-10-30 11:26:53

标签: sql firebird libreoffice-base firebird-embedded

两个表:“ S”(用于“服务”)和“付款”。它们通过“ S”捆绑在一起。“ ID-S”被称为外键:“付款”。“ S”。

我正在尝试以“添加付款”形式为下拉列表创建查询,但是由于我希望允许部分付款,因此我想减去已与给定付款相关的已付款总额“ ID-S”。但是,我似乎无法隐藏多次付款所支付的服务。

以下是我当前的代码,仅使用“服务”类别之一(在本例中为发票):

SELECT "S"."Invoice" || ' for $' || "S"."Price" -
IIF("Payments"."S" IS NULL, 0, SUM("Payments"."Amount")
AS "To-Pay", "ID-S"
FROM "S"
LEFT OUTER JOIN "Payments" ON "S"."ID-S" = "Payments"."S"
GROUP BY "S"."Invoice", "S"."Price", "Payments"."Amount", "Payments"."S", "S"."ID-S"
HAVING "Payments"."S" IS NULL OR
SUM("Payments"."Amount") < "S"."Price"

它应该显示,例如:

  • 2018年1月1日价格为$ 400
  • 2018年2月1日价格为1050美元
  • 2018年6月8日价格为750美元

等,价格为要支付的剩余价格。它根本不应该显示已完全支付的发票。

据我所知,问题在于SUM("Payments"."Amount")不会将所有具有匹配的“ S-ID”的“金额”列求和,它仅从给定行中获取“金额” 。这一点对我没有帮助,因为如果说,如果分别用两笔付款$ 1000和$ 2000偿还了$ 3000的发票,该列表不仅会显示发票,还会显示两次-一次剩余$ 2000,然后一次剩下$ 1000。

我正在将LibreOffice Base与Firebird一起使用。

编辑:在进一步输入数据后,我发现一种情况如上所示显示了双倍支付(两次使用不同的“剩余价格”),而另一种这种双倍支付则显示了一次以“ $ 0”价格显示,也许是因为被精确地分成了一半?

1 个答案:

答案 0 :(得分:0)

也许您应该将分组提取/封装到单独的查询中。很难看到没有示例数据的原因,但是请尝试使用Derived TableCommon Table Expression

以下只是Google排名最高的搜索结果,供您大致了解。

特定于Firebird的手册位于https://www.firebirdsql.org/file/documentation/reference_manuals/fblangref25-en/html/fblangref25-dml-select.html

还-您真的需要在服务器上完成所有操作,例如连接文本字符串吗?通常,它是在客户端上进行本地化和字体修饰的,而并非如此。

尝试的模式:

WITH Parts AS ( 
  SELECT ID_S, Sum(Amount) as Done 
  FROM Payments 
  GROUP BY 1
) 
SELECT S.Invoice, S.Price - COALESCE( Parts.Done, 0)
FROM Services S
LEFT JOIN Parts ON S.ID = Parts.ID_S
-- WHERE S.Price > COALESCE( Parts.Done, 0) 
WHERE S.Price > Parts.Done OR Parts.Done IS NULL

或相等模式

SELECT S.Invoice, S.Price - COALESCE( Parts.Done, 0)
FROM Services S
LEFT JOIN ( SELECT ID_S, Sum(Amount) as Done FROM Payments GROUP BY 1) 
     AS Parts ON S.ID = Parts.ID_S
-- WHERE S.Price > COALESCE( Parts.Done, 0) 
WHERE S.Price > Parts.Done OR Parts.Done IS NULL