[前][次][番号順一覧][スレッド一覧]

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]