วิธีการสร้างลำดับใน mysql


19

พิจารณาตารางนี้ใน mysql

create table numbers (number int);
insert into numbers values (3), (2), (9);
select * from numbers;

+--------+
| number |
+--------+
|      3 |
|      2 |
|      9 |
+--------+

มีแบบสอบถามง่ายๆในการสร้างตารางที่มีคอลัมน์ต่อไปนี้

  1. ตัวเลขตั้งแต่ 1 ถึง 10
  2. 1 ถ้าหมายเลขอยู่ในหมายเลขตารางและ 0 เป็นอย่างอื่น

ฉันเดาว่าคุณต้องสร้างลำดับของตัวเลขเพื่อที่จะทำสิ่งนี้ ถ้าเป็นไปได้ฉันต้องการสร้างลำดับดังกล่าวโดยไม่เก็บไว้ในฐานข้อมูล

คำถามที่เกี่ยวข้อง: มีแบบสอบถามแบบใช้เลือกข้อมูลที่สร้างลำดับของตัวเลขตั้งแต่ 1 ถึง 10 (หรือ 100 หรือ 1,000)

คำตอบ:


24

ใน MariaDB

MariaDB มีลำดับการเก็บรักษาเครื่องยนต์ ดังนั้นหากคุณใช้ MariaDB ปัญหาลำดับทั้งหมดของคุณจะจบลง (หรือเพิ่งเริ่มต้น)

ลำดับของตัวเลข 10 ตัว

select * from seq_1_to_10;

ไม่ได้ใช้แท็บเล็ต

ลำดับของตัวเลข 10 ตัว

select * from
(select 0 x union select 1 union select 2 union select 3 union select 4 union
select 5 union select 6 union select 7 union select 8 union select 9) A;

ลำดับ 100 ตัวเลข

select (t*10+u+1) x from
(select 0 t union select 1 union select 2 union select 3 union select 4 union
select 5 union select 6 union select 7 union select 8 union select 9) A,
(select 0 u union select 1 union select 2 union select 3 union select 4 union
select 5 union select 6 union select 7 union select 8 union select 9) B
order by x;

ลำดับ 1,000 ตัวเลข

select (h*100+t*10+u+1) x from
(select 0 h union select 1 union select 2 union select 3 union select 4 union
select 5 union select 6 union select 7 union select 8 union select 9) A,
(select 0 t union select 1 union select 2 union select 3 union select 4 union
select 5 union select 6 union select 7 union select 8 union select 9) B,
(select 0 u union select 1 union select 2 union select 3 union select 4 union
select 5 union select 6 union select 7 union select 8 union select 9) C
order by x;

ลำดับ 10,000 หมายเลข

select (th*1000+h*100+t*10+u+1) x from
(select 0 th union select 1 union select 2 union select 3 union select 4 union
select 5 union select 6 union select 7 union select 8 union select 9) A,
(select 0 h union select 1 union select 2 union select 3 union select 4 union
select 5 union select 6 union select 7 union select 8 union select 9) B,
(select 0 t union select 1 union select 2 union select 3 union select 4 union
select 5 union select 6 union select 7 union select 8 union select 9) C,
(select 0 u union select 1 union select 2 union select 3 union select 4 union
select 5 union select 6 union select 7 union select 8 union select 9) D
order by x;

การใช้แท็บเล็ต

ลำดับของตัวเลข 10 ตัว

use test
drop table if exists seq10;
create table seq10
(x int not null auto_increment primary key);
insert into seq10 values (),(),(),(),(),(),(),(),(),();
select * from seq10;

ลำดับ 100 ตัวเลข

use test
drop table if exists seq100;
create table seq100
(x int not null auto_increment primary key);
insert into seq100 values (),(),(),(),(),(),(),(),(),();
insert into seq100 values (),(),(),(),(),(),(),(),(),();
insert into seq100 values (),(),(),(),(),(),(),(),(),();
insert into seq100 values (),(),(),(),(),(),(),(),(),();
insert into seq100 values (),(),(),(),(),(),(),(),(),();
insert into seq100 select x + 50 from seq100;
select * from seq100;

ลำดับ 1,000 ตัวเลข

use test
drop table if exists seq1000;
create table seq1000
(x int not null auto_increment primary key);
insert into seq1000 values ();
set @p= -1;
set @p=@p+1; insert into seq1000 select x+power(2,@p) from seq1000 where (x+power(2,@p)) <= 1000;
set @p=@p+1; insert into seq1000 select x+power(2,@p) from seq1000 where (x+power(2,@p)) <= 1000;
set @p=@p+1; insert into seq1000 select x+power(2,@p) from seq1000 where (x+power(2,@p)) <= 1000;
set @p=@p+1; insert into seq1000 select x+power(2,@p) from seq1000 where (x+power(2,@p)) <= 1000;
set @p=@p+1; insert into seq1000 select x+power(2,@p) from seq1000 where (x+power(2,@p)) <= 1000;
set @p=@p+1; insert into seq1000 select x+power(2,@p) from seq1000 where (x+power(2,@p)) <= 1000;
set @p=@p+1; insert into seq1000 select x+power(2,@p) from seq1000 where (x+power(2,@p)) <= 1000;
set @p=@p+1; insert into seq1000 select x+power(2,@p) from seq1000 where (x+power(2,@p)) <= 1000;
set @p=@p+1; insert into seq1000 select x+power(2,@p) from seq1000 where (x+power(2,@p)) <= 1000;
set @p=@p+1; insert into seq1000 select x+power(2,@p) from seq1000 where (x+power(2,@p)) <= 1000;
select * from seq1000;

ลำดับของตัวเลขใด ๆ (ตัวอย่าง: 3.5 ล้าน)

use test
drop table if exists seq;
create table seq
(x int not null auto_increment primary key);
insert into seq values ();
set @maxseq = 3500000;
set @p = -1;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @p=@p+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
select max(x),count(x) from seq;

คำถามจริงของคุณ

เมื่อใช้ลำดับ0..9คุณจะเข้าร่วมลำดับกับตาราง

select A.number,1-ISNULL(B.number) present from
(select 0 number union select 1 union select 2 union select 3 union select 4 union
select 5 union select 6 union select 7 union select 8 union select 9) A
left join numbers B using (number);

ข้อมูลตัวอย่างของคุณด้วยแบบสอบถามใหม่

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

mysql> drop table if exists numbers;
Query OK, 0 rows affected, 1 warning (0.00 sec)

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

mysql> insert into numbers values (3), (2), (9);
Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> select A.number,1-ISNULL(B.number) present from
    -> (select 0 number union select 1 union select 2 union select 3 union select 4 union
    -> select 5 union select 6 union select 7 union select 8 union select 9) A
    -> left join numbers B using (number);
+--------+---------+
| number | present |
+--------+---------+
|      0 |       0 |
|      1 |       0 |
|      2 |       1 |
|      3 |       1 |
|      4 |       0 |
|      5 |       0 |
|      6 |       0 |
|      7 |       0 |
|      8 |       0 |
|      9 |       1 |
+--------+---------+
10 rows in set (0.00 sec)

mysql>

ให้มันลอง !!!


มันจะง่ายกว่านี้ไหมถ้าจะใช้ฟังก์ชั่นที่นี่? ฟังก์ชั่นที่กำหนดเองที่ส่งกลับช่วงเช่นเดียวกับ MariaDB ตามที่คุณพูดถึงrange(10,20)
azerafati

2
@Rolando - นี่เป็นวิธีที่ดีที่สุดหรือไม่? ขอเพื่อน
Max Vernon

1
@ MaxVernon ด้านนอกของ MariaDB นี่เป็นวิธีที่ฉันสร้างลำดับโดยไม่ต้องใช้ฟังก์ชั่น การไม่ใช้ตารางช่วยให้ไม่ต้องสร้างดิสก์ I / O เพื่อสร้างลำดับ
RolandoMySQLDBA

@MaxVernon ด้วยเวอร์ชัน GA ของ MySQL 8.0 ที่เพิ่งเปิดตัวใหม่ (และรุ่น MariaDB 10.2 GA ที่วางจำหน่ายเมื่อปีที่แล้ว) คุณสามารถใช้ CTE แบบเรียกซ้ำซึ่งทำให้สิ่งนี้ง่ายขึ้น เอ็นจิ้นการจัดลำดับ MariaDB นั้นง่ายที่สุด แต่ CTE แบบเรียกซ้ำอาจเป็นวิธีที่ใช้กับ MySQL และเคียวรีที่ต้องทำงานกับทั้ง MySQL และ MariaDB
dbdemon

5

ด้วย MySQL 8.0, MariaDB 10.2 และเวอร์ชันที่ใหม่กว่าคุณสามารถใช้ CTE แบบเรียกซ้ำได้ดังนั้น:

WITH RECURSIVE nums AS (
    SELECT 1 AS value
    UNION ALL
    SELECT value + 1 AS value
    FROM nums
    WHERE nums.value <= 9
)
SELECT *
FROM nums;

คุณสามารถแก้ไขสิ่งนี้ได้อย่างชัดเจนเพื่อใช้ค่าเริ่มต้นขั้นตอนและค่าสิ้นสุดที่คุณเลือก

สำหรับคำถามที่สองมันเป็นเรื่องเล็กน้อยที่จะขยายสิ่งที่กล่าวมาข้างต้น (ด้วยแรงบันดาลใจจากคำตอบของโรนัลโด):

WITH RECURSIVE nums AS (
    SELECT 1 AS value
    UNION ALL
    SELECT value + 1 AS value
    FROM nums
    WHERE nums.value <= 9
)
SELECT nums.value, 1-ISNULL(numbers.number) present
FROM nums
  LEFT JOIN numbers ON numbers.number = nums.value
ORDER BY nums.value;

แก้ไข:

MariaDB 10.3 แนะนำลำดับวัตถุ (ตามที่กำหนดไว้ในSQL Standardและตามที่เห็นในเช่น Oracle RDBMS) สิ่งเหล่านี้ไม่เป็นประโยชน์สำหรับคำถามนี้เนื่องจากค่าจะถูกเก็บไว้ในฐานข้อมูล แต่คุณลักษณะนี้อาจมีประโยชน์ในกรณีที่เกี่ยวข้องกับลำดับอื่น ๆ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.