我有一个表可以有一些有效的重复值,所以我需要一个额外的列,其中包含所述副本的外观序列号,以备将来使用。 样本可能是
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
这些值应该像(COLUMN_A, COLUMB_B, COLUMN_C)
一样唯一,但是我不能使用唯一索引,因为我也需要那些重复的值,我只需要跟踪幻影的顺序。所以我添加了一列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秒,我发现有点令人失望(已经检查过的索引并且它们正在被正确使用)之外,它的工作方式就像魅力一样,我相信问题在于使用光标。
我的问题是:有没有办法在没有光标的情况下在单个查询中设置该着名的序列号?。
答案 0 :(得分: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 :(得分: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:=@RN+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)