mysql生成連續數字或日期


1.自定義變量的方法

mysql數據庫生成連續的數字或者基於此生成連續的日期(5.7版本)

業務需要統計近24個月的平均數據,沒有數據則補0,需要保證所有日期都有。之前在oracle可以直接根據rownub生成,mysql麻煩一些,需要自定義變量,如下

SELECT 
    @xi:=@xi+1 as xc 
FROM 
    (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5) xc1, 
    (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5) xc2,  
    (SELECT @xi:=0) xc0

分析:from后邊的 SELECT @xi:=0) xc0 是定義@xi的初始值為0,另外的兩個union是為了計算多少個數據

SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5表示五次 兩個則是5×5=25個數,即25次

@xi:=@xi:+1表示每次加1.從1開始輸出25個數即【1-25】,結果如下

 類似如果想生成【41-80】,則可以修改sql為

SELECT 
    @xi:=@xi+1 as xc
FROM 
    (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5) xc1, 
    (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8) xc2,  
    (SELECT @xi:=40) xc0 

如果想生成連續時間可以繼續改下sql如下,生成最近24個月的日期

SELECT DATE_FORMAT(DATE_SUB(NOW(), INTERVAL xc MONTH), '%Y-%m') as date
FROM ( 
            SELECT @xi:=@xi+1 as xc from 
            (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5) xc1, 
            (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5) xc2,  
            (SELECT @xi:=0) xc0 
) xcxc

2.存儲過程的方法

寫存儲過程,這個就會方便很多

drop table t;
create table t(id int);

DELIMITER //

create procedure p_ins_seq(in pi_num int)
BEGIN

   declare l_n1 int default 1;

   truncate table t;

   while l_n1 <= pi_num DO  
     insert into t values (l_n1);
     set l_n1 = l_n1 + 1;
   end while;

end;

DELIMITER  ;

call p_ins_seq(50);

測試記錄

mysql>
mysql> drop table t;
Query OK, 0 rows affected (0.01 sec)

mysql> create table t(id int);
Query OK, 0 rows affected (0.02 sec)

mysql>
mysql>
mysql> DELIMITER //
mysql> create procedure p_ins_seq(in pi_num int)
    -> BEGIN
    ->
    ->    declare l_n1 int default 1;
    ->
    ->    truncate table t;
    ->
    ->    while l_n1 <= pi_num DO
    ->      insert into t values (l_n1);
    ->      set l_n1 = l_n1 + 1;
    ->    end while;
    ->
    -> end;
    -> //
Query OK, 0 rows affected (0.01 sec)
mysql>
mysql> DELIMITER ;
mysql>
mysql>
mysql> call p_ins_seq(50);
Query OK, 1 row affected (0.14 sec)

mysql>
mysql> select * from t;
+------+
| id   |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
|    5 |
|    6 |
|    7 |
|    8 |
|    9 |
|   10 |
|   11 |
|   12 |
|   13 |
|   14 |
|   15 |
|   16 |
|   17 |
|   18 |
|   19 |
|   20 |
|   21 |
|   22 |
|   23 |
|   24 |
|   25 |
|   26 |
|   27 |
|   28 |
|   29 |
|   30 |
|   31 |
|   32 |
|   33 |
|   34 |
|   35 |
|   36 |
|   37 |
|   38 |
|   39 |
|   40 |
|   41 |
|   42 |
|   43 |
|   44 |
|   45 |
|   46 |
|   47 |
|   48 |
|   49 |
|   50 |
+------+
50 rows in set (0.00 sec)

3.With遞歸方法(MySQL 8.0)

MySQL 8.0開始支持with語法后,這個就大大的簡便了

with recursive c(n) AS
(
select 1
union ALL
select n + 1
from c
where n < 50
)
select * from c;

測試記錄

mysql> with recursive c(n) AS
    -> (
    -> select 1
    -> union ALL
    -> select n + 1
    -> from c
    -> where n < 50
    -> )
    -> select * from c;
+------+
| n    |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
|    5 |
|    6 |
|    7 |
|    8 |
|    9 |
|   10 |
|   11 |
|   12 |
|   13 |
|   14 |
|   15 |
|   16 |
|   17 |
|   18 |
|   19 |
|   20 |
|   21 |
|   22 |
|   23 |
|   24 |
|   25 |
|   26 |
|   27 |
|   28 |
|   29 |
|   30 |
|   31 |
|   32 |
|   33 |
|   34 |
|   35 |
|   36 |
|   37 |
|   38 |
|   39 |
|   40 |
|   41 |
|   42 |
|   43 |
|   44 |
|   45 |
|   46 |
|   47 |
|   48 |
|   49 |
|   50 |
+------+
50 rows in set (0.00 sec)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM