【发布时间】:2021-09-12 00:11:56
【问题描述】:
我有以下表格:
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 小提琴here
【问题讨论】:
-
提醒:SQL Server 2005 已经完全不支持大约 5 年了。它存在已知的安全问题,并且根本不支持许多在较新版本上被视为理所当然的语法。您真的应该尽快查看升级路径。
-
事实上,您确定您使用的是 2005 年吗?
VALUES表结构是在 SQL Server 2008 中引入的。 -
通常在 GROUP BY 子句中包含未出现在 SELECT 列表中的列表明您想要的目标与您的查询不完全匹配。那么你的结果集代表什么?按 InvoiceID 分组意味着您在 invoice 级别请求信息,但您的选择列表意味着您需要供应商级别的值。而且您还遇到了同一供应商具有多个代码的附加问题。明确那个目标。你的输出应该基于样本数据吗?
-
@SMor,最终结果应该是每个供应商的清单及其发票价值和收到的付款,就像我现在得到的查询结果一样,但按供应商分组。
-
空白不花钱,你知道的。如果您使用的是更高版本,则可以删除该
left join并将其替换为第一个表上的窗口聚合ISNULL(SUM(SUM(b.PaidAmount)) OVER (PARTITION BY InvoiceID), 0)
标签: sql-server group-by sql-server-2005 sum left-join