sql-server - LEFT JOIN 返回重复的 SUM 值
问题描述
我有以下表格:
create table Invoices
(
InvoiceID int,
InvoiceNumber int,
InvoiceDate date,
SupplierName varchar(250),
SupplierCode varchar(20),
InvoiceValue decimal(18,2)
);
insert into Invoices (InvoiceID, InvoiceNumber, InvoiceDate, SupplierName, SupplierCode, InvoiceValue) values
(1,700,'2021-01-01','ACME','A01',978.32),
(2,701,'2021-01-02','MACROD','A02',772.81),
(3,702,'2021-01-03','CODECO','A03',938.20),
(4,703,'2021-01-04','ACME','A03',892.18),
(5,704,'2021-01-05','CODECO','A03',791.41),
(6,705,'2021-01-06','DRONIX','A04',469.03);
create table Payments
(
InvoiceID int,
PaymentDate date,
PaymentValue decimal(18,2)
);
insert into Payments (InvoiceID, PaymentDate, PaymentValue) values
(1, '2021-01-11', 500.00),
(1, '2021-01-12', 50.00),
(1, '2021-02-13', 100.00),
(3, '2021-02-14', 10.00),
(4, '2021-03-15', 200.00),
(3, '2021-03-16', 300.00),
(5, '2021-04-17', 75.00),
(1, '2021-04-18', 30.00);
这是我正在使用的查询:
SELECT
a.SupplierName,
a.SupplierCode,
SUM(a.TotalInvoiceValue),
ISNULL(SUM(b.PaidAmount), 0),
SUM(a.TotalInvoiceValue) - ISNULL(SUM(b.PaidAmount), 0)
FROM (
SELECT
InvoiceID,
SupplierName,
SupplierCode,
SUM(InvoiceValue) AS TotalInvoiceValue
FROM Invoices
WHERE InvoiceDate BETWEEN '2021-01-01 00:00:00' AND '2021-01-31 23:59:29'
GROUP BY
InvoiceID,
SupplierName,
SupplierCode
) a
LEFT JOIN (
SELECT
InvoiceID,
ISNULL(SUM(PaymentValue),0) AS PaidAmount
FROM Payments
GROUP BY InvoiceID
) b
ON a.InvoiceID=b.InvoiceID
GROUP BY
a.InvoiceID,
a.SupplierName,
a.SupplierCode
ORDER BY
a.SupplierName
上面的查询为 Payments 表中的相同 SupplierName 返回多行。
我正在使用 Microsoft SQL Server 2005。
在此处查看 SQL 小提琴
解决方案
因为您按 (a.InvoiceID、a.SupplierName、a.SupplierCode) 分组,所以发票 ID、供应商名称和供应商代码的每个组合都有不同的记录。尝试按您的选择语句中的非聚合字段分组以返回不同的汇总行(在这种情况下,不要按发票 ID 分组,因为它不在您的选择语句中)。
在这种情况下,您选择 SupplierName 和 SupplierCode。这将复制每个供应商代码的供应商名称。如果您想要 SupplierName 的不同摘要记录,请不要选择供应商代码。
使用供应商代码
SELECT a.SupplierName,
a.SupplierCode,
SUM(a.TotalInvoiceValue),
ISNULL(SUM(b.PaidAmount),0),
SUM(a.TotalInvoiceValue)-ISNULL(SUM(b.PaidAmount),0)
FROM
(SELECT InvoiceID, SupplierName, SupplierCode, SUM(InvoiceValue) AS TotalInvoiceValue FROM Invoices
WHERE InvoiceDate BETWEEN '2021-01-01 00:00:00' AND '2021-01-31 23:59:29'
GROUP BY InvoiceID, SupplierName, SupplierCode) a
LEFT JOIN
(SELECT InvoiceID, ISNULL(SUM(PaymentValue),0) AS PaidAmount FROM Payments GROUP BY InvoiceID) b
ON a.InvoiceID=b.InvoiceID
GROUP BY a.SupplierName, a.SupplierCode
ORDER BY a.SupplierName
没有供应商代码
SELECT a.SupplierName,
SUM(a.TotalInvoiceValue),
ISNULL(SUM(b.PaidAmount),0),
SUM(a.TotalInvoiceValue)-ISNULL(SUM(b.PaidAmount),0)
FROM
(SELECT InvoiceID, SupplierName, SupplierCode, SUM(InvoiceValue) AS TotalInvoiceValue FROM Invoices
WHERE InvoiceDate BETWEEN '2021-01-01 00:00:00' AND '2021-01-31 23:59:29'
GROUP BY InvoiceID, SupplierName, SupplierCode) a
LEFT JOIN
(SELECT InvoiceID, ISNULL(SUM(PaymentValue),0) AS PaidAmount FROM Payments GROUP BY InvoiceID) b
ON a.InvoiceID=b.InvoiceID
GROUP BY a.SupplierName
ORDER BY a.SupplierName
推荐阅读
- python - 如何在字符串中找到所有可能的连续三元组?
- javascript - 需要正则表达式来比较字符串中的最后一个数字
- php - 基于 Cookie 的身份验证 - 客户端
- github - 使用 github webhooks 配置成功/失败通知
- android - 如何在 Android 上实现应用内购买并处理一些逻辑以增加我的服务器上的积分?
- c - 在 while 循环中使用 scanf() 读取分段错误字符串
- android - 在 Jenkins 上上传 android 构建(.apk 文件)只是为了运行自动化套件而不是构建 android apk
- c++ - 当我对 std::vector 使用自定义排序时,为什么要使用 const 引用?
- python - Google Ads API:创建 IpBlockInfo 实例
- r - ggplot geom_smooth 对象中最陡峭的回归线的颜色代码