2009年5月22日

[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@xxxxx>:
> 柴垣といいます。
> @変数を使った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@xxxxx
>
> _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
>
>
>
>


投稿者 xml-rpc : 2009年5月22日 01:44
役に立ちました?:
過去のフィードバック 平均:(0) 総合:(0) 投票回数:(0)
本記事へのTrackback: http://hoop.euqset.org/blog/mt-tb2006.cgi/85259
トラックバック
コメント
コメントする




画像の中に見える文字を入力してください。