【问题标题】:MySQL: Using variables inside SELECT statementMySQL:在 SELECT 语句中使用变量
【发布时间】:2015-01-27 12:06:52
【问题描述】:

请看下面的声明

INSERT INTO Ongoing_Fees (currentDate, Gross_Fee, Insurance_Fee, Submit_Fee)
    SELECT current_timestamp, New.Gross_Fee,
           @InsuranceFee := (New.Gross_Fee)*(p.E_Fee/100),
           @SubmitFee := @InsuranceFee-(p.s_Fee/100)
    FROM Portfolio p
    WHERE p.idPortfolio = New.idPortfolio;

这里我使用了 2 个用户定义变量,@InsuranceFee@SubmitFee。如您所见,您可以通过从@InsuranceFee 中减去一个值来获得@SubmitFee

现在,为了使其工作,@InsuranceFee“必须”首先被评估。但是MySQL document 在下面说

作为一般规则,除了在 SET 语句中,您不应该 为用户变量赋值并读取相同的值 陈述。例如,要增加一个变量,这是可以的:

SET @a = @a + 1;对于其他语句,例如 SELECT,您可能会得到 您期望的结果,但这不能保证。在下面的 语句,你可能会认为 MySQL 会先评估 @a 然后 第二次做作业:

选择@a, @a:=@a+1, ...;但是,评估顺序为 涉及用户变量的表达式未定义。

那么,在SELECT 中使用变量的最佳方式是什么?

更新

可能首先使用单独的 SELECT 语句将值分配给变量更好?像下面这样...

 SET   @InsuranceFee :=    New.Gross_Fee * ((SELECT E_Fee FROM Portfolio WHERE idPortfolio = New.idPortfolio)/100);

 SET   @SubmitFee := @InsuranceFee - ((SELECT s_FeeFROM Portfolio WHERE idPortfolio = New.idPortfolio)/100)

    INSERT INTO Ongoing_Fees (currentDate, Gross_Fee, Insurance_Fee, Submit_Fee)
           current_timestamp, New.Gross_Fee,
                   @InsuranceFee ,
                   @SubmitFee

【问题讨论】:

  • 在这种情况下使用9.4 User-Defined Variables 是不安全的,我会寻找新的选项(也许使用13.6.6 Cursors)来达到目标​​。
  • 为什么在这种情况下需要使用user-defined variables?只需使用(New.Gross_Fee)*(p.E_Fee/100)-(p.s_Fee/100)
  • @sgeddes:你愿意使用((New.Gross_Fee)*(p.E_Fee/100))-((((New.Gross_Fee)*(p.E_Fee/100))*(p.I_Fee/100))+(((New.Gross_Fee)*(p.E_Fee/100)-(((Gross_Fee)*(p.E_Fee/100))*(p.I_Fee/100)))*0.2)) 之类的东西吗?这是我真正的查询内容..
  • @wchiquito:请检查我的更新。
  • 正如您在下面的SQL Fiddle 中看到的那样,您的选择是完全有效的,但是,您的选择必须对Portfolio 表进行两次查询。 @sgeddes 提出的解决方案在单个子查询中获取两个值并避免使用9.4 User-Defined Variables,如下面的SQL Fiddle 所示。

标签: mysql sql database variables select


【解决方案1】:

User-defined variables 不应该这样使用。正如我在评论中提到的,没有理由不把它全部写出来。然而,如果你只是喜欢临时语法,你总是可以使用子查询:

INSERT INTO Ongoing_Fees (currentDate, Gross_Fee, Insurance_Fee, Submit_Fee)
SELECT ct, gross_fee, InsuranceFee, InsuranceFee-SubmitFee
FROM (
    SELECT current_timestamp ct, 
       New.Gross_Fee,
       New.Gross_Fee*p.E_Fee/100 as InsuranceFee,
       p.s_Fee/100 as SubmitFee
    FROM Portfolio p
    WHERE p.idPortfolio = New.idPortfolio
) T

【讨论】:

  • @Sniper -- 当你可以在 1 中完成所有操作时,为什么还要运行 3 条 sql 语句?您是否还有其他要求说您必须使用user-defined variables?子查询将是一种更好的方法,并且可以利用临时值。话虽如此,在我看来,把它全部写出来没有错。
  • 没什么错,但超级难编辑。例如,我在评论中给出的查询,您可以轻松编辑它吗?除此之外,还有很多地方我们必须使用条件,比如“如果这条记录不存在,那么 0 是值,否则 1 是值”等等。当你有 3-4 个这样的条件时,写下来在“一次”可能不是问题,但是当出现问题时,除非使用变量清楚地写入,否则很难阅读和编辑。
猜你喜欢
  • 1970-01-01
  • 2013-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-03
  • 1970-01-01
相关资源
最近更新 更多