mysql:14869
From: "N.K." <"N.K." <nakai.kanako@xxxxxxxxxx>>
Date: Fri, 22 May 2009 01:44:52 +0900
Subject: [mysql 14869] Re: @変数の動作について
私の環境では1番目のクエリもセッション接続後の初回実行時は、期待されている結果が戻らなかったです。 mysql> select version(); +------------------+ | version() | +------------------+ | 5.1.34-community | +------------------+ 1 row in set mysql> select @code,if(T.code=@code,'same','new') as Mark,@code:=T.code as Code from T order by T.code; +-------+------+------+ | @code | Mark | Code | +-------+------+------+ | NULL | new | a | | NULL | new | a | | NULL | new | a | | NULL | new | b | | NULL | new | b | | NULL | new | c | | NULL | new | c | +-------+------+------+ 7 rows in set mysql> select @code,if(T.code=@code,'same','new') as Mark,@code:=T.code as Code from T order by T.code; +-------+------+------+ | @code | Mark | Code | +-------+------+------+ | c | new | a | | a | same | a | | a | same | a | | a | new | b | | b | same | b | | b | new | c | | c | same | c | +-------+------+------+ 7 rows in set 同一セッションで2回目実行時に期待する結果になっているのは、 前回実行の最後にセットしている"c"が残っているからのようです。 ユーザ変数を使用される前に、初期化すると初回実行時でも期待されている結果にはなりました。 mysql> set @code="";select @code,if(T.code=@code,'same','new') as Mark,@code:=T.code as Code,M.name from T left join M on T.code=M.code order by T.code; Query OK, 0 rows affected +-------+------+------+------+ | @code | Mark | Code | name | +-------+------+------+------+ | | new | a | ASM | | a | same | a | ASM | | a | same | a | ASM | | a | new | b | BAS | | b | same | b | BAS | | b | new | c | COM | | c | same | c | COM | +-------+------+------+------+ 7 rows in set 2009/05/22 0:44 柴垣 <akiro@xxxxxxxxxx>: > 柴垣といいます。 > @変数を使ったsql文の動作について、気づいたことを書きます。 > > 例えば、下のようなテーブル T があって > +------+ > | code | > +------+ > | a | > | b | > | a | > | c | > | b | > | a | > | c | > +------+ > > select if(T.code=@code,'same','new') as Mark,@code:=T.code as Code > from T order by T.code; > > としてソートすると、下のような結果が返ってきます。 > +------+------+ > | Mark | Code | > +------+------+ > | new | a | > | same | a | > | same | a | > | new | b | > | same | b | > | new | c | > | same | c | > +------+------+ > ここまでは期待通りです。 > > > ところが、下のような別のテーブル M を用意して、 > +------+------+ > | code | name | > +------+------+ > | a | ASM | > | b | BAS | > | c | COM | > +------+------+ > > select if(T.code=@code,'same','new') as Mark,@code:=T.code as Code, > M.name > from T left join M on T.code=M.code order by T.code; > > のようにnameフィールドを付け加えて出力しようとすると、 > +------+------+------+ > | Mark | Code | name | > +------+------+------+ > | new | a | ASM | > | new | a | ASM | > | new | a | ASM | > | new | b | BAS | > | new | b | BAS | > | new | c | COM | > | new | c | COM | > +------+------+------+ > となってしまいます。 > > 「from」の部分を、fromT,M と書いてみたりすることから始めて > 多くの行からこのデータセットが抽出されていく過程を追うことで > @code の挙動は一応理解したのですが、出力を > +------+------+------+ > | Mark | Code | name | > +------+------+------+ > | new | a | ASM | > | same | a | ASM | > | same | a | ASM | > | new | b | BAS | > | same | b | BAS | > | new | c | COM | > | same | c | COM | > +------+------+------+ > とする工夫はないものでしょうか。 > (あまり一般性がないかもしれない内容で、申し訳ありません。) > > > _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ > > 柴垣 akiro@xxxxxxxxxx > > _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ > > > >
14868 2009-05-22 00:44 [柴垣 <akiro@xxxxxxxx] @変数の動作について -> 14869 2009-05-22 01:44 ┗["N.K." <nakai.kanako] 14870 2009-05-22 09:16 ┗[柴垣 <akiro@xxxxxxxx] 14871 2009-05-22 09:50 ┗["N.K." <nakai.kanako] 14872 2009-05-22 12:06 ┗[柴垣 <akiro@xxxxxxxx]