每次交付的运费

时间:2018-12-17 09:32:54

标签: sql tsql

我是SQL的初学者,并且遇到了一个小问题,希望您能为我提供帮助。我要实现的目标:我要计算每次送货的运费,具体取决于路线和重量。

为此,我有一个表(装运3350),其中包含了一定时期内的所有装运,因此它包含交货编号,路线,重量等。我想将表装运与表运费一起加入计算每次交货的运费。表格运费基本上包括不同的路线,重量类别和价格(根据所运输的重量,一条路线可以具有不同的成本)。此外,还要考虑到表中的货物不是干净的,我需要删除重复的货物(交货号可能会弹出几次,但实际情况并非如此)

这就是我所做的。基本上,我创建了2个CTE,后来加入了。结果看起来很有希望。但是,我有一个问题要解决。如上所述,价格取决于路线和相应的重量。但是,每条路线的运费取决于重量。即路线abc,重量在0到5kg之间5欧元,> 5千克但<10千克10欧元,依此类推。因此,查询应基于在交货时找到的路线和重量信息来识别正确的货运成本。有时这失败了(选择了错误的运费),我不知道需要更改什么。 因此,我的问题是我的代码中是否存在明显的错误,使我无法获得正确的运费?

With CTE1 as 
(
Select row_number() over (Partition by  [Delivery] order by [Delivery]) as ROWID 
,[Delivery]
,[Total Weight]
,[CTY]
,[Route]
,[Shipment]
,[SearchTerm]
,[Shipment route]
,[Shipping Conditions]
from [BAAS_PowerBI].[dbo].[Shipments 3350 ]
)
, CTE2 as
(select * from(
select [route],[Lower Scale quantity limit],[Upper scale quantity limit],[Amount],[sales org]
from [BAAS_PowerBI].[dbo].[RM35_freight rates 27112018 test] 
)x where x.[sales org]=3350)


Select * from CTE1
left join CTE2
on [CTE1].[route] = [CTE2].[route]
where [Total Weight] <[Upper scale quantity limit]  and [Total Weight] >=[Lower Scale quantity limit] and ROWID=1 

You can see from the pictures that the query has selected the wrong weight category. It should have selected the category 0-10Kg and not 30-55Kg

1 个答案:

答案 0 :(得分:1)

channel

无效,因为您的列是字符串,并且例如对于字符串'10'小于'2',因为在字符表(ANSI,ASCII,UNICODE,好吧,不管它是什么。)

但是您的where [Total Weight] < [Upper scale quantity limit] and [Total Weight] >= [Lower Scale quantity limit] 子句还有另一个问题:它使您的外部联接仅是内部联接。这是原因:

使用CTE1

[Delivery]   [Route]   [Total Weight]
A            X         6
B            X         60
C            Y         6

和CTE2

[Route]   [Lower Scale quantity limit]   [Upper scale quantity limit]
X         1                              10
X         11                             20

此声明:

WHERE

导致

[Delivery]   [Route]   [Total Weight]   [Lower Scale quantity limit]   [Upper scale quantity limit]
A            X         6                1                              10
A            X         6                11                             20
B            X         60               1                              10
B            X         60               11                             20
C            Y         6                null                           null

select * from cte1 left join cte2 on cte1.route = cte2.route 子句

WHERE

将其减少为:

[Delivery]   [Route]   [Total Weight]   [Lower Scale quantity limit]   [Upper scale quantity limit]
A            X         6                1                              10

,因为只有这一行符合条件。此结果与内部联接的结果完全相同。

您真正想要的不是连接所有路由匹配甚至保留不匹配路由的外部联接(where [Total Weight] < [Upper scale quantity limit] and [Total Weight] >= [Lower Scale quantity limit] 所做的),而是连接所有路由/范围匹配的外部联接甚至保留没有匹配路线/范围的路线/总计:

left join cte2 on cte1.route = cte2.route
[Delivery]   [Route]   [Total Weight]   [Lower Scale quantity limit]   [Upper scale quantity limit]
A            X         6                1                              10
B            X         60               null                           null
C            Y         6                null                           null

在这里,如果CTE2中没有匹配项,则将每个CTE1行与它们匹配的CTE2行或一个由空值组成的虚拟CTE2行连接起来。

({select * from cte1 left join cte2 on cte1.route = cte2.route and [Total Weight] < [Upper scale quantity limit] and [Total Weight] >= [Lower Scale quantity limit] 属于ROWID=1子句,因为这与要加入CTE1的CTE2行无关,而只是说出您要考虑的CTE1行。错误地将WHERE放在ROWID=1子句中,您也会突然选择 all 个CTE1行,但只查找与ON匹配的CTE2行。)< / p>

简而言之:当您外部连接表时,请将其所有连接条件放在ROWID=1子句中。