Bel*_*igh 4 sql-server t-sql sql-server-2008-r2
我有 3 张表正在使用Right Join
。数据设置如下 - 我的问题是返回的数字不准确,因此当我执行查询时,我得到了返回(这是准确值的两倍和三倍)
vendor TotalSales TotalCases
Vendor 1 61.40 6
Run Code Online (Sandbox Code Playgroud)
但如果你手动计算它应该是
vendor TotalSales TotalCases
Vendor 1 30.70 2
Run Code Online (Sandbox Code Playgroud)
我必须在查询中更改哪些内容才能返回上述结果?
Declare @BBC Table
(
vendor varchar(250)
,vendorcasenum varchar(100)
,casenumdate date
)
Declare @AllVendor Table
(
vendor varchar(250)
)
Declare @TotalSalesAmt Table
(
vendor varchar(250)
,saleamt decimal(10,2)
)
Insert Into @TotalSalesAmt (vendor, saleamt) VALUES
('Vendor 1', '10.20'), ('Vendor 2', '10.10'), ('Vendor 1', '.40')
,('Vendor 1', '20.10'), ('Vendor 2', '20.10'), ('Vendor 3', '20.00')
Insert Into @AllVendor (vendor) Values
('Vendor 1'), ('Vendor 2'), ('Vendor 3'), ('Vendor 4')
,('Vendor 5'), ('Vendor 6'), ('Vendor 7'), ('Vendor 8')
,('Vendor 9'), ('Vendor 10'), ('Vendor 11'), ('Vendor 12')
,('Vendor 13'), ('Vendor 14'), ('Vendor 15'), ('Vendor 16')
,('Vendor 17'), ('Vendor 18'), ('Vendor 19'), ('Vendor 20')
Insert Into @BBC (vendor, vendorcasenum, casenumdate) VALUES
('Vendor 11', 'A12344', '2017-01-19')
,('Vendor 10', 'A12311', '2014-05-12')
,('Vendor 9', 'A12889', '2015-07-10')
,('Vendor 8', 'A12988', '2016-07-01')
,('Vendor 7', 'A12931', '2012-03-07')
,('Vendor 6', 'A12199', '2011-10-05')
,('Vendor 5', 'E12331', '2011-10-11')
,('Vendor 4', 'E12391', '2014-12-16')
,('Vendor 3', 'E12300', '2011-07-15')
,('Vendor 2', 'E11001', '2011-06-15')
,('Vendor 1', 'E12301', '2013-11-06')
,('Vendor 1', 'E12221', '2013-11-06')
Select
av.vendor
,TotalSales = SUM(ISNULL(tsa.saleamt,0))
,TotalCases = COUNT(bbc.vendorcasenum)
FROM @AllVendor av
LEFT JOIN @BBC bbc
ON av.vendor = bbc.vendor
LEFT JOIN @TotalSalesAmt tsa
ON tsa.vendor = av.vendor
GROUP BY av.vendor
ORDER BY av.vendor ASC
Run Code Online (Sandbox Code Playgroud)
编辑
我也尝试使用 aCTE
来实现我想要的结果,但得到了同样不正确的结果:
WITH tsa As
(
Select
vendor
,saleamt
FROM @TotalSalesAmt
)
,BBC As
(
Select
vendor
,vendorcasenum
FROM @BBC
)
Select
av.vendor
,TotalSales = ISNULL(SUM(tsa.saleamt),0)
,TotalCases = COUNT(bbc.vendorcasenum)
FROM @AllVendor av
LEFT JOIN TSA tsa
ON tsa.vendor = av.vendor
LEFT JOIN BBC bbc
ON bbc.vendor = av.vendor
GROUP BY av.vendor
ORDER BY av.vendor
Run Code Online (Sandbox Code Playgroud)
如果您在没有聚合的情况下运行查询,您将看到正在发生的事情:
Select
*
FROM @AllVendor av
LEFT JOIN @BBC bbc
ON av.vendor = bbc.vendor
LEFT JOIN @TotalSalesAmt tsa
ON tsa.vendor = av.vendor
where av.vendor = 'vendor 1'
+----------+----------+---------------+---------------------+----------+---------+
| vendor | vendor | vendorcasenum | casenumdate | vendor | saleamt |
+----------+----------+---------------+---------------------+----------+---------+
| Vendor 1 | Vendor 1 | E12301 | 06.11.2013 00:00:00 | Vendor 1 | 10,20 |
| Vendor 1 | Vendor 1 | E12301 | 06.11.2013 00:00:00 | Vendor 1 | 0,40 |
| Vendor 1 | Vendor 1 | E12301 | 06.11.2013 00:00:00 | Vendor 1 | 20,10 |
| Vendor 1 | Vendor 1 | E12221 | 06.11.2013 00:00:00 | Vendor 1 | 10,20 |
| Vendor 1 | Vendor 1 | E12221 | 06.11.2013 00:00:00 | Vendor 1 | 0,40 |
| Vendor 1 | Vendor 1 | E12221 | 06.11.2013 00:00:00 | Vendor 1 | 20,10 |
+----------+----------+---------------+---------------------+----------+---------+
Run Code Online (Sandbox Code Playgroud)
由于@BBC 表中有 2 行Vendor 1
:
('Vendor 1', 'E12301', '2013-11-06')
('Vendor 1', 'E12221', '2013-11-06')
Run Code Online (Sandbox Code Playgroud)
聚合的 SUM(saleamt) = 61.40
您可以使用一个子查询来计算SUM(saleamt)
,另一个来计算COUNT(vendorcasenum)
:
Select
vendor,
(select ISNULL(SUM(tsa.saleamt),0)
from @TotalSalesAmt tsa
where tsa.vendor = av.vendor) TotalSales,
(select COUNT(bbc.vendorcasenum)
from @BBC bbc
where av.vendor = bbc.vendor) TotalCases
FROM @AllVendor av
ORDER BY av.vendor ASC;
Run Code Online (Sandbox Code Playgroud)
这是最终结果:
+-----------+------------+------------+
| vendor | TotalSales | TotalCases |
+-----------+------------+------------+
| Vendor 1 | 30,70 | 2 |
| Vendor 10 | 0,00 | 1 |
| Vendor 11 | 0,00 | 1 |
| Vendor 12 | 0,00 | 0 |
| Vendor 13 | 0,00 | 0 |
| Vendor 14 | 0,00 | 0 |
| Vendor 15 | 0,00 | 0 |
| Vendor 16 | 0,00 | 0 |
| Vendor 17 | 0,00 | 0 |
| Vendor 18 | 0,00 | 0 |
| Vendor 19 | 0,00 | 0 |
| Vendor 2 | 30,20 | 1 |
| Vendor 20 | 0,00 | 0 |
| Vendor 3 | 20,00 | 1 |
| Vendor 4 | 0,00 | 1 |
| Vendor 5 | 0,00 | 1 |
| Vendor 6 | 0,00 | 1 |
| Vendor 7 | 0,00 | 1 |
| Vendor 8 | 0,00 | 1 |
| Vendor 9 | 0,00 | 1 |
+-----------+------------+------------+
Run Code Online (Sandbox Code Playgroud)
还有另一种方法,没有内联子查询,你GROUP BY
先加入,然后加入,有 3 种风格:
OUTER APPLY
使用 CTE:
WITH
tsa AS
(
SELECT
vendor
TotalSales = SUM(saleamt)
FROM @TotalSalesAmt
GROUP BY vendor
),
bbc AS
(
SELECT
vendor,
TotalCases = COUNT(vendorcasenum)
FROM @BBC
GROUP BY vendor
)
SELECT
av.vendor,
TotalSales = COALESCE(tsa.TotalSales, 0),
TotalCases = COALESCE(bbc.TotalCases, 0)
FROM
@AllVendor AS av
LEFT JOIN tsa
ON tsa.vendor = av.vendor
LEFT JOIN bbc
ON bbc.vendor = av.vendor
ORDER BY
av.vendor ;
Run Code Online (Sandbox Code Playgroud)