You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在单行数据中复用子查询定义的@ConversionRate变量

问题解答

你的需求是可行的,但不能用你当前的变量赋值方式——在SELECT语句中直接给变量赋值的行为不可靠,SQL Server不保证变量会逐行更新并在当前行的后续列中使用最新值,很可能出现所有行复用同一个汇率的错误情况。

正确的做法是用CROSS APPLY先为每行计算出对应的汇率,再在查询中直接复用这个计算好的值,既保证单行内汇率固定,又能让每行使用自己对应的汇率,效率也不受影响。

修正后的完整代码

DECLARE @CurrencyType VARCHAR(10) = 'USD/GBP'

-- 创建汇率表
CREATE TABLE CurrencyRate (
    CURCODE VARCHAR(8),
    CURDATE VARCHAR(8),
    CURRATE DECIMAL(18,6)
)

-- 插入汇率数据(修正原数据列顺序错误)
INSERT INTO CurrencyRate (CURCODE, CURDATE, CURRATE)
VALUES
    ('USD/AED', '20231001', 3.672775),
    ('USD/GBP', '20231001', 0.81671),
    ('USD/AED', '20231101', 3.672435),
    ('USD/GBP', '20231101', 0.80671)

-- 创建乘客票价表
CREATE TABLE PassengerFare (
   ID INT,
   CreateDate DATE,
   PName NVARCHAR(50),
   [Desc] NVARCHAR(50),
   FareTotal DECIMAL(18,2),
   FareDiscount DECIMAL(18,2)
)

-- 插入乘客票价数据
INSERT INTO PassengerFare (ID, CreateDate, PName, [Desc], FareTotal, FareDiscount)
VALUES
    (1, '2023-09-14', 'Mark P.', 'OneWay', 178.75, 15.00),
    (2, '2023-10-11', 'Jeff H.', 'TwoWay', 319.50, 30.00)

-- 核心查询:用CROSS APPLY每行计算一次汇率,然后复用
SELECT
    pf.PName,
    pf.CreateDate,
    pf.FareTotal * cr.CURRATE AS ConvertedFareTotal,
    pf.FareDiscount * cr.CURRATE AS ConvertedFareDiscount
FROM PassengerFare pf
CROSS APPLY (
    -- 为当前行的乘客日期匹配最新的有效汇率
    SELECT TOP 1 c.CURRATE
    FROM CurrencyRate c WITH (NOLOCK)
    WHERE c.CURCODE = @CurrencyType 
      AND c.CURDATE <= CONVERT(VARCHAR, pf.CreateDate, 112)
    ORDER BY c.CURDATE DESC
) cr

-- 清理临时表
DROP TABLE IF EXISTS PassengerFare
DROP TABLE IF EXISTS CurrencyRate

关键说明

  • CROSS APPLY会为PassengerFare的每一行执行一次子查询,计算出该行对应的汇率并存储在cr结果集中
  • 同一行的ConvertedFareTotal和ConvertedFareDiscount直接复用cr.CURRATE,避免重复计算
  • 这种方式既保证了每行汇率的正确性,又实现了单行内复用计算结果的需求,执行效率稳定可靠

内容的提问来源于stack exchange,提问作者Bill

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 02:17:09