2017-07-21 14 views
0

私はいくつかの有効な重複値を持つことができるテーブルを持っているので、将来の使用のために複製の出現順番の列を追加する必要があります。 サンプルは値が(COLUMN_A, COLUMB_B, COLUMN_C)のようなユニークなことになっているが、私は同様にそれらの重複値を必要とするので、私は、私はちょうど幻影の順序を追跡する必要があり、ユニークなインデックスを使用することはできませんmysqlにカーソルなしのシークエンス番号を追加するにはどうしたらいいですか?

ROW | COLUMN_A | COLUMN_B | COLUMN_C | SEQ_NUM <= Want this column 
1  A   B   1   1 
2  A   B   1   2 
3  A   B   2   1 
4  A   B   2   2 
5  A   B   2   3 

かもしれません。だから私は、これらの繰り返しを追跡するために列SEQ_NUMを追加しました。

、私はこのようにそれを埋める:

begin 
     declare done boolean default false; 
     declare _A varchar(1); 
     declare _B varchar(1); 
     declare _C integer unsigned; 
     declare cur cursor for 
      select COLUMN_A , COLUMN_B , COLUMN_C 
      from tmp_horario 
      group by COLUMN_A , COLUMN_B , COLUMN_C 
      having count(*) > 1; -- Here I loop throught the repeated values 
     declare continue handler for not found set done := true; 
     open cur; 
     loop_dup: loop 
      fetch cur into _A, _B, _C; 
      if done then 
       leave loop_dup; 
      end if; 
      set @_seq = 0; -- I initialize my sequence in 0 to start 
      update tmp_table h 
      set h.SEQ_NUM = (@_seq := @_seq + 1) -- Set the next sequential to the repeated values 
      where h.COLUMN_A = _A 
       and h.COLUMN_B = _B 
       and h.COLUMN_C = _C; 

     end loop loop_dup; 

     close cur; 
    end; 

注:表は、カーソルを作る方法以上のカラム(にフェッチ)大きな痛みを持っています。 これは魅力的なものですが、私の店は20秒から80秒になりますが、私は少し失望しています(既にチェックされているインデックスと彼らは正しく使用されています)。カーソル。

私の質問は次のとおりです。その有名な連番をカーソルなしの1つのクエリで設定する方法はありますか?あなたはあなたのようなこの操作を行うことができ、テーブルに値を挿入すると、この現象が発生したいと仮定すると、

答えて

1

INSERT INTO tmp_horario(COLUMN_A, COLUMN_B, COLUMN_C, SEQ_NUM) 
VALUE(A_VAL, B_VAL, C_VAL, (IFNULL((
    SELECT MAX(SEQ_NUM) 
    FROM tmp_horario AS a 
    WHERE a.COLUMN_A = A_VAL AND a.COLUMN_B = B_VAL AND a.COLUMN_C = C_VAL), 0)+1)); 

基本的な前提はあなたが同じ値を持つ行を探している、最大シーケンシャル値を取得新しい値のためにそれを追加してください。一致するものが見つからない場合は、挿入値を1に設定します。 IFNULLステートメントは、このクエリを適合させる必要がある場合は、SEQ_NUMを取得するために必要なものです。

1

はい、かなりあなたのカーソルのような

DROP TABLE IF EXISTS T; 
    CREATE TABLE T(ROW INT, COLUMN_A VARCHAR(1), COLUMN_B VARCHAR(1), COLUMN_C VARCHAR(1), SEQ_NUM INT); 
    INSERT INTO T VALUES 
    (1 ,  'A' ,   'B'  , 1,NULL), 
    (2 ,  'A' ,   'B'  , 1,NULL), 
    (3 ,  'A' ,   'B'  , 2,NULL), 
    (4 ,  'A' ,   'B'  , 2,NULL), 
    (5 ,  'A' ,   'B'  , 2,NULL); 

UPDATE T 
JOIN (
SELECT T.ROW, 
       IF(CONCAT(T.COLUMN_A,T.COLUMN_B,T.COLUMN_C) <> @P , @RN:=1,@RN:[email protected]+1) RN, 
       @P:=CONCAT(T.COLUMN_A,T.COLUMN_B,T.COLUMN_C) P 
      FROM T , (SELECT @RN:=0,@P:=0) R 
      ORDER BY ROW 

     ) S ON S.ROW = T.ROW 
SET SEQ_NUM = S.RN 
WHERE 1 = 1 

MariaDB [sandbox]> SELECT * FROM T; 
+------+----------+----------+----------+---------+ 
| ROW | COLUMN_A | COLUMN_B | COLUMN_C | SEQ_NUM | 
+------+----------+----------+----------+---------+ 
| 1 | A  | B  | 1  |  1 | 
| 2 | A  | B  | 1  |  2 | 
| 3 | A  | B  | 2  |  1 | 
| 4 | A  | B  | 2  |  2 | 
| 5 | A  | B  | 2  |  3 | 
+------+----------+----------+----------+---------+ 
5 rows in set (0.00 sec) 
関連する問題