[英]Update an column in SQL Server with values from a different lookup table?
我正在處理一個項目,我需要更新當前為空白的郵寄費率列。 根據送貨服務的類型,我有幾個不同的費率/成本表。 每個表中基本上都有一個重量和區域表,其中成本取決於重量(y 列)和行駛距離(x 列)。
我需要更新的表格列出了每封郵件的各種遞送服務類型、相關重量和相關距離。 我無法弄清楚如何編寫查詢以更新此表中與相應表對每項服務的重量/行程距離查找相匹配的 rate 列的邏輯。
以下是表的示例:
| Type of Service | Weight | Distance | Cost |
+-----------------+----------+----------+----------+
| A | 1 | 15 | ? |
| B | 2 | 20 | ? |
| C | 3 | 10 | ? |
| | | | |
| Service A Table | | | |
| Weight | 10 km | 15 km | 20 km |
| 1 | $25.00 | $30.00 | $40.00 |
| 2 | $27.00 | $32.00 | $41.00 |
| 3 | $28.00 | $34.00 | $43.00 |
| | | | |
| Service B Table | | | |
| Weight | 10 km | 15 km | 20 km |
| 1 | $28.00 | $32.00 | $41.00 |
| 2 | $29.00 | $35.00 | $44.00 |
| 3 | $30.00 | $37.00 | $47.00 |
+-----------------+----------+----------+----------+
您可以在要計算成本的主表和服務表之間使用MERGE
語句。 進行重量和距離的合並,並根據服務類型計算成本。
查閱合並文檔應該很容易做到。 我可以在這里做,但更好地為你學習。
這里有一個例子: https : //www.sqlservertutorial.net/sql-server-basics/sql-server-merge/
您可以使用left join
引入所有表。 . . 以及很多case
邏輯來選擇列:
update t
set cost = (case when distance = '10 km'
then coalesce(sa.10km, sb.10km, sc.10km)
when distance = '15 km'
then coalesce(sa.15km, sb.15km, sc.15km)
when distance = '20 km'
then coalesce(sa.20km, sb.20km, sc.20km)
end)
from t left join
servicea sa
on sa.weight = t.weight and t.service = 'A' left join
servicea sb
on sb.weight = t.weight and t.service = 'B' left join
servicea sc
on sc.weight = t.weight and t.service = 'C' ;
由於每種類型的服務都有不同的表,因此如果添加新類型的服務對您來說會很困難。 服務類型最好是成本表中的一列。 如果出於某種原因您想以這種方式查看數據,您可以為每種類型的服務創建視圖。 我會像這樣組織數據以便於查找:
create table ServiceCosts(
ServiceType char(1),
MaxDistance decimal(9, 2),
Cost decimal(9, 2),
constraint pk_ServiceCosts primary key clustered (ServiceType, MaxDistance)
)
然后您可以使用外部應用更新表:
update s
set s.Cost = oa.Cost
from SourceTable s
outer apply (
select top(1) Cost
from ServiceCosts sc
where sc.Weight >= s.Weight
and sc.Distance >= s.Distance
order by Cost -- cheapest that fits under weight and distance
) oa
您可以使用幾個選項,哪個選項最好取決於您的數據的確切標准。 每張桌子都有不同的重量嗎? 每個距離? 如果沒有符合您標准的記錄(此處的成本為空),您會怎么做?
另一種選擇是創建一個函數......
create function GetCost(
@ServiceType char(1),
@Weight decimal(9, 2),
@Distance decimal(9, 2)
) returns decimal(9, 2)
as
begin
declare @Cost decimal(9, 2) = null;
if @ServiceType = 'A'
select top(1) @Cost = case
when @Distance < 10 then [10 km]
when @Distance < 20 then [20 km]
when @Distance < 30 then [30 km]
else null
end
from ServiceATable
where Weight >= @Weight order by Weight -- least weight at or above limit
else if -- repeat for each service table
return @Cost;
end
然后更新:
update ItemTable
set Cost = GetCost(ServiceType, Weigth, Distance)
where Cost is null; -- only update rows without Cost already
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.