iT邦幫忙

0

MYSQL的 WHILE迴圈 案例分享

前幾天在解題的過程中發現MYSQL提供了一個WHILE函式,不過從官方的文件照抄一直都有語法錯誤的問題,
https://dev.mysql.com/doc/refman/5.6/en/while.html
後來找到的解法是要改變分隔苻才能夠使用,下面是可以正常跑的查詢,不過很可惜的是跟我想要的結果不一樣,
原本的需求是例如有10筆交易,希望第1筆能夠跟第2筆做比較,第2筆跟第3筆如此類推......
想說把WHILE的結果放在WHERE當條件查詢,不過實際跑起來會變成迴圈跑一次查一次,看起來比較適合做INSERT資料之類的,只能當成案例分享了~

DELIMITER $$
DROP PROCEDURE IF EXISTS dowhile$$
CREATE PROCEDURE dowhile()
	BEGIN
		DECLARE v1 INT DEFAULT 1;
		WHILE v1 < 4 DO
		
			SELECT * FROM `my_table` WHERE `id` = v1;
			SET v1 = v1 + 1;

		END WHILE;
	END$$
DELIMITER ;	
call dowhile();	

喔對了如果有人有更進階的用法或是知道我原本的需求怎麼解也麻煩教教我 /images/emoticon/emoticon01.gif


1 則留言

0
一級屠豬士
iT邦大師 1 級 ‧ 2020-03-10 14:37:56

while 不是函式,是 MySQL 的 Procedure Language 的語法.
若要做跟次一筆資料比較,可以使用 Window function 的 lead(),
MySQL 從8版開始支援.範例如下

create table it200310 (
  id int unsigned not null auto_increment primary key
, ival int unsigned not null
);

insert into it200310(ival)
select floor(rand() * 100)
  from performance_schema.global_variables
 limit 10;

select id
     , ival
     , lead(ival) over() as "下一筆"
     , lead(ival,2) over() as "下兩筆"
  from it200310
 order by id;
 
+----+------+-----------+-----------+
| id | ival | 下一筆    | 下兩筆    |
+----+------+-----------+-----------+
|  1 |   38 |        43 |         1 |
|  2 |   43 |         1 |        75 |
|  3 |    1 |        75 |        76 |
|  4 |   75 |        76 |        52 |
|  5 |   76 |        52 |        34 |
|  6 |   52 |        34 |        16 |
|  7 |   34 |        16 |        77 |
|  8 |   16 |        77 |        36 |
|  9 |   77 |        36 |      NULL |
| 10 |   36 |      NULL |      NULL |
+----+------+-----------+-----------+
10 rows in set (0.00 sec)
看更多先前的回應...收起先前的回應...
jasonb122 iT邦新手 5 級 ‧ 2020-03-10 15:45:49 檢舉

原來是這樣! 剛剛用local測試的確lead能實現我要的結果
不過剛剛發現sever用的是5.5.6.......
看來要再想想有沒有替代方案了哈哈哈/images/emoticon/emoticon02.gif

jasonb122 iT邦新手 5 級 ‧ 2020-03-10 15:50:46 檢舉

大大想加問一題 剛剛想用變數實做一樣的結果
不過好像沒辦法讓SELECT的子查詢使用資料表a 這是語言限制還是只是我用法錯了?
SET @row = 0;
SET @row1 = 1;
SELECT *
,(SELECT datetime FROM a WHERE novalue = @row1 ORDER BY novalue LIMIT 0,1) as next_time1
,(SELECT datetime FROM a WHERE novalue = @row1+1 ORDER BY novalue LIMIT 0,1) as next_time2
FROM
(
SELECT @row:=@row+1 AS novalue, trxn.*
FROM trxn
) AS a

你另外開一個發問的,把範例資料準備好,還有你想要達到的結果.
程式碼要用Markdown 弄好.不然這樣很難互動.

jasonb122 iT邦新手 5 級 ‧ 2020-03-10 16:02:29 檢舉

好的

我要留言

立即登入留言