sql-server - SQL 查询 - 如何通过总和数获得最小的费用金额
问题描述
我遇到了 SQL Server 查询问题,这让我卡了 2 天。所以,我必须计算符合这个条件的最小费用:
有1.8的尺寸津贴,如果超过1.8,他们将收取额外的费用:
Size| Additional Charge Amount
------------------------------
0.3 | $1000
0.6 | $2000
0.9 | $3000
1.2 | $3000
例如 :
示例 1:
Size| Additional Charge Amount
------------------------------
0.3 | $1000
0.6 | $0
1.2 | $0
这种情况有 2 个选项:
- 0.3 和 0.6 在 1.8 的津贴,所以 1.2 将收取 $3000
- 0.6 和 1.2 在 1.8 的津贴,所以 0.3 将收取 $1000
在这种情况下,最小收费金额为 1000 美元,因此额外收费金额为 0.3 美元,对应 1000 美元
示例 2:
Size| Additional Charge Amount
------------------------------
0.6 | $0
0.6 | $0
0.6 | $0
1.2 | $3000
在这种情况下,我们有 2 个选项:
- 津贴:第三个 0.6 和最后一个 1.2,因此第一个和第二个数据的大小 0.6 将收取额外金额,结果 $2000 + $2000 = $4000 或
- 津贴:第一、第二和第三个 0.6,因此尺寸 1.2 将被收取额外金额,结果为 $3000。
因为我们必须收取最小的金额,所以额外的收费金额将是 1.2 码,即 3000 美元。
示例 3:
Size| Additional Charge Amount
------------------------------
0.6 | $2000
0.6 | $0
1.2 | $0
本案将收取2000美元,因为0.6和1.2的津贴,所以前0.6将收取额外的金额。
示例 4:
Size| Additional Charge Amount
------------------------------
0.3 | $0
0.3 | $0
0.6 | $0
0.6 | $0
这种情况不会产生额外费用。
所以,我的想法是,我必须知道哪个更大的数字总和为 1.8,所以我知道小尺寸。因为,尺寸越大,附加费用越贵。但是,如果我有这个逻辑,示例 2 将返回错误的结果(4000 美元)。
你们对如何处理这个案子有任何想法吗?我尝试了很多方法并寻找类似的案例,但我一无所获。任何人都可以帮忙吗?
解决方案
它根据大小的升序或降序确定哪些尺寸是收费的,哪些不是收费的,然后比较应收费的总金额以确定哪些是收费的。
注:引入 a以按要求的方式ID
计算 的累积和。size
-- create sample table & data
declare @charge table
(
size decimal(4,1),
charge int
)
insert into @charge (size, charge)
values (0.3, 1000), (0.6, 2000), (0.9, 3000), (1.2, 3000)
declare @sample1 table
(
id int identity,
size decimal(4,1)
)
insert into @sample1 (size)
values (0.3), (0.6), (1.2)
declare @sample2 table
(
id int identity,
size decimal(4,1)
)
insert into @sample2 (size)
values (0.6), (0.6), (0.6), (1.2)
declare @sample3 table
(
id int identity,
size decimal(4,1)
)
insert into @sample3 (size)
values (0.6), (0.6), (1.2)
declare @sample4 table
(
id int identity,
size decimal(4,1)
)
insert into @sample4 (size)
values (0.3), (0.3), (0.6), (0.6)
-- the query
; with
-- this cte gets the charge for each size. `cumm_size` is cummulative
-- running total for the size in ascending order (a) or descending order (d)
cte as
(
select s.size, c.charge,
cumm_size_a = sum(s.size) over (order by s.size, id),
cumm_size_d = sum(s.size) over (order by s.size desc, id)
from @sample1 s
inner join @charge c on s.size = c.size
),
-- this cte determine the charge by inspecting the value of `cumm_size`
-- less than 1.8, charge = 0
cte2 as
(
select *,
charge_a = case when cumm_size_a <= 1.8 then 0 else charge end,
charge_d = case when cumm_size_d <= 1.8 then 0 else charge end
from cte
)
-- last part of the query
-- `sum(charge) over()` will gives you the total charge
-- comparing it between the ascending and descending method and return the lower of both
select size,
charge = case when sum(charge_a) over() > sum(charge_d) over()
then charge_d
else charge_a
end
from cte2 c
order by c.size
推荐阅读
- javascript - 我可以使用正则表达式捕获组来防止该组的连续匹配吗?
- reactjs - 仅在条件为真时测试显示按钮
- sql - 插入语句 Oracle
- mysql - 我试图了解如何使用 TFDStoredProc(FireDac 组件)填充 TIWDBGrid(IntraWeb 组件)
- python - Python - “石头剪刀布”逻辑条件的简化
- javascript - 无法读取未定义的属性“_header”
- r - 意外的循环行为将 ggplot2 参数传递给列表
- scikit-learn - 模块“sklearn.metrics”没有属性“davies_bouldin_score”
- c++ - 如何在用户定义的张量流操作中使用随机数?
- java - 如何从链表堆栈推送或弹出