複雑な concat_ws 式の一部として「隠し」割り当てを行うと、派生テーブルとサブクエリを回避できます
割り当ては、独自の列に座っているのではなく、列の最終的な目的の値の式の一部であるため、MySQL が正しい順序で評価するかどうかを心配する必要はありません。言うまでもなく、複数の列で一時変数を使用する場合は、すべての賭けがオフになります:-/
注意: これは MySQL 5.1.73 で行いました。それ以降のバージョンでは変更されている可能性があります
concat はそうではありませんが、null 引数を空の文字列に結合するため、すべてをconcat_wsでラップします。
var @stampへの割り当てをifでラップして、連結される引数になるのではなく「消費」されるようにします。補足として、ユーザーレコードが最初に作成されたときに u.status_timestamp が入力されることを別の場所で保証しました。次に、 @stamp がdate_formatの 2 つの場所で使用されます。フォーマットされる日付と、使用するフォーマットを選択するネストされた if の両方です。最後の連結は時間範囲 "hh" であり、c レコードが存在する場合は他の場所に存在することが保証されています。
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
同様に、2 番目のフィドル (壊れているように見えます) の右側は次のようになります。
SELECT concat_ws( '', if(@QID := 2+2,'',''), @QID + 1) AS THN