1

ストアド プロシージャや関数ではなく、クエリ内で一時変数を作成できるようにしたいと考えています。これは、呼び出すときにクエリ パラメータを渡す必要がないように、宣言して設定する必要はありません。

これに向かって努力しようとしています:

   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

4 に答える 4

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 は 2 番目の引数が 3 番目の引数の前に評価されることを保証しないため、これはギャンブルです。実際には動作するようですが、保証されていません。

于 2013-08-28T00:26:33.987 に答える
1

複雑な 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
于 2020-06-04T19:43:34.680 に答える
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

于 2013-08-28T18:46:26.543 に答える