Wie erstelle ich einen Zeilengenerator in MySQL?
Frage
Gibt es eine Möglichkeit, eine beliebige Anzahl von Zeilen zu generieren, die in einem JOIN ähnlich der Oracle-Syntax verwendet werden können:
SELECT LEVEL FROM DUAL CONNECT BY LEVEL<=10
Lösung
Hass, dies zu sagen, aber MySQL
ist der einzige RDBMS
der großen vier, die diese Funktion nicht hat.
In Oracle
:
SELECT *
FROM dual
CONNECT BY
level < n
In MS SQL
(bis Zeilen 100
):
WITH hier(row) AS
(
SELECT 1
UNION ALL
SELECT row + 1
FROM hier
WHERE row < n
)
SELECT *
FROM hier
oder nach oben mit Hinweis auf 32768
WITH hier(row) AS
(
SELECT 1
UNION ALL
SELECT row + 1
FROM hier
WHERE row < 32768
)
SELECT *
FROM hier
OPTION (MAXRECURSION 32767) -- 32767 is the maximum value of the hint
In PostgreSQL
:
SELECT *
FROM generate_series (1, n)
In MySQL
, nichts.
Andere Tipps
Soweit ich weiß, können Sie in MySql mit einem SELECT ohne Tabelle (oder DUAL) mehr als eine Zeile erhalten.
Um mehrere Zeilen zu erhalten, müssen Sie daher Tun benötigen eine reale oder temporäre Tabelle mit mindestens der erforderlichen Anzahl an Zeilen.
Jedoch, Sie müssen keine temporäre Tabelle erstellen wie Sie verwenden können BELIEBIG vorhandene Tabelle, die mindestens die erforderliche Anzahl an Zeilen enthält.Wenn Sie also eine Tabelle mit mindestens der erforderlichen Anzahl an Zeilen haben, verwenden Sie Folgendes:
SELECT @curRow := @curRow + 1 AS row_number
FROM sometable
JOIN (SELECT @curRow := 0) r
WHERE @curRow<100;
Ersetzen Sie einfach „sometable“ durch den Namen einer Ihrer Tabellen mit mindestens der erforderlichen Anzahl von Zeilen.
PS:Das „r“ ist ein Tabellen-„Alias“:Ich hätte „AS r“ verwenden können.Jede Unterabfrage in einer FROM- oder JOIN-Klausel erstellt eine „abgeleitete Tabelle“, die wie alle Tabellen einen Namen oder Alias haben muss.(Siehe MySql-Handbuch:13.2.9.8.Unterabfragen in der FROM-Klausel)
Da dies zur Zeit ist eines der ersten Ergebnisse in Google für „mysql Reihe Generator“, werde ich ein Update hinzufügen.
Wenn Ihr Geschmack von MySQL geschieht MariaDB sein, sie haben diese Funktion. Es ist die „Sequence-Speicher-Engine“ und es wird wie folgt verwendet genannt :
select * from seq_1_to_10;
Mit den Ergebnissen:
+-----+
| seq |
+-----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
| 9 |
| 10 |
+-----+
10 rows in set (0.00 sec)
Bis zur Version 10.0 wurde ein separates Plugin, das explizit installiert werden mußte, sondern von 10,0 ff ist es eingebaut. Genießen Sie!
I hatte eine Tabelle mit einer Spalte (c5
), die eine Anzahl x enthalten ist, I benötigt, um einen SQL-Ausdruck, die die gleichen Zeile x Zahlen von Malen wiederholt.
Meine Tabelle A enthalten:
c1 c2 c3 c4 c5
16 1 2 16 3
16 1 2 17 2
16 1 2 18 1
Und ich brauchte:
c1 c2 c3 c4 c5 n
16 1 2 16 3 1
16 1 2 16 3 2
16 1 2 16 3 3
16 1 2 17 2 1
16 1 2 17 2 2
16 1 2 18 1 1
I gelöst, dass mit dem Ausdruck:
SELECT
c1, c2, c3, c4, c5, row_number AS n
FROM
(
SELECT
@curRow := @curRow + 1 AS row_number
FROM
tablea
JOIN (SELECT @curRow := 0) r
WHERE
@curRow < (
SELECT
max(field1)
FROM
tablea
)
) AS vwtable2
LEFT JOIN tablea d ON vwtable2.row_number <= tablea.field1;
Wenn ich Sie zu verstehen, wollen Sie eine Liste von consequtive Zahlen?
Sie einfach die Liste machen:
create table artificial_range (id int not null primary key auto_increment, idn int);
insert into artificial_range (idn) values (0); --first row
insert into artificial_range(idn) select idn from artificial_range; --2nd
insert into artificial_range(idn) select idn from artificial_range; -- now 4 rows
insert into artificial_range(idn) select idn from artificial_range; --8
insert into artificial_range(idn) select idn from artificial_range; --16
insert into artificial_range(idn) select idn from artificial_range; --32
insert into artificial_range(idn) select idn from artificial_range; --64
insert into artificial_range(idn) select idn from artificial_range; --128
... usw., bis Sie haben, sagen wir, 1024.
update artificial_range set idn = id - 1 ;
- jetzt haben Sie eine Reihe an 1 (id) starren und eine Reihe beginnend bei 0
Nun, um es zu kommen, oder zu Transformationen davon kommen:
create view days_this_century as
select date_add('2000-01-01', interval a.idn day) as cdate
from artificial_range;
Ich weiß nicht, ob das hilft, aber Sie können die Zeilen aus jeder select-Anweisung mit etw nummerieren. wie:
SET @NUM = 0;
SELECT @NUM: = @ NUM + 1 rowNumber, * FROM ...
Und später kommen sie auf diese. Bei großen Datenbanken kann dies sehr langsam sein.
So generieren 10 Zeilen:
SELECT a AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 from dual
Sie können generieren 100 Zeilen mit weiteren 10 Reihen einen Join machen:
select t2.a*10 + t1.a from
(SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) t1,
(SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) t2
Und dann 1000 Zeilen mit einem anderen verbinden, ...