1

次のように、値が重複または欠落しているソート列をリセットしています。

set @last='';
set @sort=NULL;
update conf_profile set sort=
    if(
        @last=(@last:=concat(org_id,',',profile_type_id,',',page,',',col)),
        (@sort:=@sort+1),
        (@sort:=0)
    )
order by org_id,profile_type_id,page,col,sort,id;

(順次増加する値をソートに割り当てるいくつかのキー フィールドによってソートされたすべての行を調べます。これらのフィールドのいずれかが変更されるたびに、0 から再開します。)

更新を行う前に @sort 変数が作成された場合にのみ機能するようです (ただし、設定されているものは関係ありません)。「set @sort」を指定しないと、すべてのソート値が 0 または NULL に設定されます。

なぜこれがそうなるのですか?MySQL バージョン 5.0.51。

更新: ロジックを詳しく説明するには: 最初の行では、@last=(@last:=...) は常に false になり、その後、キー フィールドのいずれかが前の行から変更されると false になります。 . (注意: 連結されるキー フィールドはいずれも NULL ではありません)。false の場合は、並べ替えカウンターを 0 から再度開始し (@sort:=0)、それ以外の場合はインクリメントされ (@sort:=@sort+1)、新しい値が使用されます。

update ステートメントで設定される前に @sort が使用されることは決してありません。

4

1 に答える 1

3

設定されていないユーザー変数はNULL、式で参照されているかのように扱われます。

SQL では、NULL+ 1 は を返しますNULL。これより前に@sort非値に設定しないと、何度評価してもそのままになります。を実行すると、正常に増加するはずです。 NULLUPDATENULL@sort:=@sort+1@sort:=0

で実行せずにこれを試してくださいUPDATE

mysql> set @sort := NULL;
mysql> SELECT @sort; -- returns NULL
mysql> set @sort := @sort + 1;
mysql> SELECT @sort; -- returns NULL again
mysql> set @sort := 0;
mysql> set @sort := @sort + 1;
mysql> SELECT @sort; -- returns 1

初めて設定した後に重複がないのは偶然だと思います@sort:=0

編集:上記は当てはまりますが、ご指摘のとおり@sort、最初の行の評価中に論理的に 0 に設定する必要があるため、表示されている動作を説明していません。

ただし、式の項の順序を変更すると、開始時に が設定されていIF()なくても、すべて機能することに気付きました。@sort

set @last='';
-- set @sort=NULL;
update conf_profile set sort=
    if(
        @last!=(@last:=concat(org_id,',',profile_type_id,',',page,',',col)),
        (@sort:=0),
        (@sort:=@sort+1)
    )
order by org_id,profile_type_id,page,col,sort,id;

これが機能する理由を正確に説明するのに十分なほどよく理解しているかどうかはわかりませんが、ユーザー変数がいつ評価されるかについては奇妙なことがあります。多くの例と詳細については、このブログを参照してください: 「高度な MySQL ユーザー変数テクニック」。

于 2008-12-04T20:26:51.260 に答える