如果您将“隐藏”赋值作为复杂 concat_ws 表达式的一部分,则可以避免派生表和子查询
由于赋值是列的最终期望值表达式的一部分,而不是坐在它自己的列中,因此您不必担心 MySQL 是否会以正确的顺序评估它。不用说,如果你想在多列中使用 temp var,那么所有的赌注都没有了:-/
警告:我在 MySQL 5.1.73 中这样做了;在以后的版本中可能会发生变化
我将所有内容都包装在concat_ws中,因为它将 null args 合并为空字符串,而 concat 没有。
我将分配给 var @stamp 包装在if中,以便它被“消耗”而不是成为要连接的 arg。作为旁注,我在其他地方保证 u.status_timestamp 在首次创建用户记录时被填充。然后 @stamp 在date_format的两个地方使用,既作为要格式化的日期,又在嵌套的 if 中选择要使用的格式。最后的 concat 是一个小时范围“hh”,如果 c 记录存在,我保证在其他地方存在,否则它的 null 返回由外部 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's answer中的第一个小提琴并将右手查询更改为
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