在查询中创建临时变量

时间:2013-08-28 00:22:07

标签: mysql sql

我希望能够在查询中创建临时变量 - 不是存储过程或函数 - 不需要声明和设置,这样我就不需要传递查询参数了叫它。

努力做到这一点:

   Select field1,
       tempvariable=2+2,
       newlycreatedfield=tempvariable*existingfield
From
       table

远离这个:

DECLARE @tempvariable
SET @tempvariable = 2+2
Select field1,
       newlycreatedfield=@tempvariable*existingfield
From
       table

感谢您的时间

我可能过于复杂的例子;更简单地说,以下内容给出了无效的列名称QID

Select
QID = 1+1
THN = QID + 1

如果它位于查询中,是否有解决方法?

4 个答案:

答案 0 :(得分:1)

您可以使用子查询执行此操作:

Select field1, tempvariable,
       (tempvariable*existingfield) as newlycreatedfield
from (select t.*, (2+2) as tempvariable
      from table t
     ) t;

不幸的是,MySQL倾向于实际实例化(即创建)子查询的派生表。大多数其他数据库足够聪明,可以避免这种情况。

您可以赌博以下内容:

Select field1, (@tempvariable := 2+2) as tempvariable,
       (@tempvariable*existingfield) as newlycreatedfield
From table t;

这是一场赌博,因为MySQL并不保证在第三个参数之前评估第二个参数。它似乎在实践中起作用,但并不能保证。

答案 1 :(得分:0)

您可以这样做:

SELECT field1, tv.tempvariable,
       (tv.tempvariable*existingfield) AS newlycreatedfield
FROM table1
INNER JOIN (SELECT 2+2 AS tempvariable) AS tv

请参阅SQLFIDDLE:http://www.sqlfiddle.com/#!2/8b0724/8/0

并参考您的简化示例:

SELECT var.QID,
(var.QID + 1) AS THN
FROM (SELECT 1+1 as QID) AS var

请参阅SQLFIDDLE:http://www.sqlfiddle.com/#!2/d41d8/19140/0

答案 2 :(得分:0)

为什么不只是:

SET @sum = 4 + 7;
SELECT @sum;

输出:

+------+
| @sum |
+------+
|   11 |
+------+

source

答案 3 :(得分:0)

如果您将“隐藏”分配作为复杂的concat_ws表达式的一部分进行操作,则可以避免派生表和子查询

由于赋值是该列最终期望值表达的一部分,而不是坐在它自己的列中,因此您不必担心MySQL是否会以正确的顺序对其求值。不用说,如果您想在多列中使用temp var,则所有选择都关闭了:-/

caveat:我在MySQL 5.1.73中做到了;以后的版本中情况可能会发生变化

我将所有内容都包装在 concat_ws 中,因为它将空args合并为空字符串,而concat则没有。

我将赋值包装到 if 中的变量 @stamp 中,以使其“消耗”而不是成为要串联的arg。附带说明一下,我保证在其他地方首次创建用户记录时会填充u.status_timestamp。然后@stamp在两个地方以 date_format 形式使用,既是要格式化的日期,又在嵌套的位置(如果要选择要使用的格式)。最后的concat是小时范围“ h-h”,如果c记录存在,我保证在其他地方存在,否则如上所述,其空返回值将由外部concat_ws合并。

SELECT
concat_ws( '', if( @stamp := ifnull( cs.checkin_stamp, u.status_timestamp ), '', '' ),
  date_format( @stamp, if( timestampdiff( day, @stamp, now() )<120, '%a %b %e', "%b %e %Y" )),
  concat( ' ', time_format( cs.start, '%l' ), '-', time_format( cs.end, '%l' )) 
) AS as_of
FROM dbi_user AS u LEFT JOIN
  (SELECT c.u_id, c.checkin_stamp, s.start, s.end FROM dbi_claim AS c LEFT JOIN
  dbi_shift AS s ON(c.shift_id=s.id) ORDER BY c.u_id, c.checkin_stamp DESC) AS cs
ON (cs.u_id=u.id) WHERE u.status='active' GROUP BY u.id ;

最后一点:在此示例中,我碰巧使用了派生表,但这仅是因为要求为每个用户获取最新的索赔记录及其关联的班次记录。如果临时变量的计算中不涉及复杂的联接,则可能不需要派生表。可以通过转到@Fabien TheSolution答案的第一个小提琴并将右手查询更改为

来证明这一点。
Select field1, concat_ws( '', if(@tempvariable := 2+2,'','') ,
       @tempvariable*existingfield ) as newlycreatedfield
from table1

同样,第二个小提琴(似乎已损坏)的右侧为

SELECT concat_ws( '', if(@QID := 2+2,'',''), @QID + 1) AS THN