it-swarm.com.de

So generieren Sie eine Sequenz in MySQL

Betrachten Sie diese Tabelle in MySQL

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

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

Gibt es eine einfache Abfrage zum Generieren einer Tabelle mit den folgenden Spalten?

  1. Die Zahlen von 1 bis 10
  2. 1, wenn die Nummer in den Tabellennummern vorhanden ist, und 0, wenn dies nicht der Fall ist

Ich denke, Sie müssen eine Folge von Zahlen erstellen, um dies zu tun. Wenn möglich, möchte ich eine solche Sequenz erstellen, ohne sie in der Datenbank zu speichern.

Verwandte Frage: Gibt es eine Auswahlabfrage, die eine Folge von Zahlen von 1 bis 10 (oder 100 oder 1000) generiert?

21
sjdh

IN MariaDB

MariaDB hat eine SEQUENCE Storage Engine . Wenn Sie also MariaDB verwenden, sind alle Ihre Sequenzprobleme beendet (oder haben gerade erst begonnen).

Folge von 10 Zahlen

select * from seq_1_to_10;

TABELLEN NICHT VERWENDEN

Folge von 10 Zahlen

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;

Folge von 100 Zahlen

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;

Folge von 1000 Zahlen

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;

Folge von 10000 Zahlen

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;

TABELLEN VERWENDEN

Folge von 10 Zahlen

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;

Folge von 100 Zahlen

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;

Folge von 1000 Zahlen

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 @[email protected]+1; insert into seq1000 select x+power(2,@p) from seq1000 where (x+power(2,@p)) <= 1000;
set @[email protected]+1; insert into seq1000 select x+power(2,@p) from seq1000 where (x+power(2,@p)) <= 1000;
set @[email protected]+1; insert into seq1000 select x+power(2,@p) from seq1000 where (x+power(2,@p)) <= 1000;
set @[email protected]+1; insert into seq1000 select x+power(2,@p) from seq1000 where (x+power(2,@p)) <= 1000;
set @[email protected]+1; insert into seq1000 select x+power(2,@p) from seq1000 where (x+power(2,@p)) <= 1000;
set @[email protected]+1; insert into seq1000 select x+power(2,@p) from seq1000 where (x+power(2,@p)) <= 1000;
set @[email protected]+1; insert into seq1000 select x+power(2,@p) from seq1000 where (x+power(2,@p)) <= 1000;
set @[email protected]+1; insert into seq1000 select x+power(2,@p) from seq1000 where (x+power(2,@p)) <= 1000;
set @[email protected]+1; insert into seq1000 select x+power(2,@p) from seq1000 where (x+power(2,@p)) <= 1000;
set @[email protected]+1; insert into seq1000 select x+power(2,@p) from seq1000 where (x+power(2,@p)) <= 1000;
select * from seq1000;

Reihenfolge beliebiger Zahlen (Beispiel: 3,5 Millionen)

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 @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
set @[email protected]+1; insert into seq select x+power(2,@p) from seq where (x+power(2,@p)) <= @maxseq;
select max(x),count(x) from seq;

IHRE TATSÄCHLICHE FRAGE

Verwenden der Sequenz 0..9, du hast die Sequenz gegen die Tabelle verbunden

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);

Ihre Beispieldaten mit der neuen Abfrage

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>

VERSUCHE ES !!!

26
RolandoMySQLDBA

Mit MySQL 8.0, MariaDB 10.2 und späteren Versionen können Sie rekursive CTEs verwenden.

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

Sie können dies natürlich ändern, um den Startwert, den Schritt- und den Endwert Ihrer Wahl zu verwenden.

Was die zweite Frage betrifft, ist es dann trivial, das Obige zu erweitern (mit Inspiration aus einem Teil von Ronaldos Antwort):

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;

Hinweis: CTEs sind begrenzt durch cte_max_recursion_depth (Standard 1000) in MySQL, während in MariaDB die Variable max_recursive_iterations (Standard 4294967295).

Bearbeiten:

MariaDB 10.3 eingeführt Sequenzobjekte (wie im SQL Standard definiert und wie z.B. das Oracle RDBMS). Diese sind für diese spezielle Frage nicht hilfreich, da die Werte in der Datenbank gespeichert sind. Die Funktion kann jedoch in anderen sequenzbezogenen Anwendungsfällen hilfreich sein.

8
dbdemon