Come faccio a fare un generatore di fila in MySQL?
Domanda
C'è un modo per generare un numero arbitrario di righe che possono essere utilizzati in un join simile alla sintassi Oracle:
SELECT LEVEL FROM DUAL CONNECT BY LEVEL<=10
Soluzione
Odio dire questo, ma è l'unica MySQL
RDBMS
delle quattro grandi che non hanno questa caratteristica.
In Oracle
:
SELECT *
FROM dual
CONNECT BY
level < n
In MS SQL
(fino a 100
righe):
WITH hier(row) AS
(
SELECT 1
UNION ALL
SELECT row + 1
FROM hier
WHERE row < n
)
SELECT *
FROM hier
o utilizzando suggerimento fino a 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
, nulla.
Altri suggerimenti
In MySql, è la mia capire che si può ottenere più di una riga con una SELECT con nessuna tabella (o DUAL).
Quindi, per ottenere più righe, fa bisogno di un vero tavolo o temporaneo con almeno il numero di righe.
Tuttavia, non c'è bisogno di costruire una tabella temporanea , come si può usare ANY tabella esistente che ha almeno il numero di righe necessarie. Quindi, se si dispone di un tavolo con almeno il numero di righe, usare:
SELECT @curRow := @curRow + 1 AS row_number
FROM sometable
JOIN (SELECT @curRow := 0) r
WHERE @curRow<100;
Basta sostituire "SomeTable" con il nome di qualsiasi tabella di tuo con almeno il numero di righe.
PS: La "r" è un tavolo "alias": avrei potuto usare "AS r". Qualsiasi subquery in una FROM o JOIN clausola crea una "tabella derivata" che, come con tutte le tabelle, deve avere un nome o un alias. (Vedere il manuale di MySQL:. 13.2.9.8 subquery nella clausola FROM)
Dal momento che questo è attualmente uno dei primi risultati in Google per "generatore di fila mysql", aggiungerò un aggiornamento.
Se il sapore di MySQL sembra essere MariaDB, hanno questa caratteristica. Si chiama "Sequenza motore di archiviazione" ed è utilizzato come questo :
select * from seq_1_to_10;
Con i risultati:
+-----+
| seq |
+-----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
| 9 |
| 10 |
+-----+
10 rows in set (0.00 sec)
Fino alla versione 10.0 è stato un plug-in separato che aveva bisogno di essere esplicitamente installato, ma da 10,0 in poi è costruito in. Buon divertimento!
avevo una tabella con una colonna (c5
) che conteneva un numero x, avevo bisogno un'espressione SQL che ripete gli stessi numeri di riga x di volte.
La mia tabella A conteneva:
c1 c2 c3 c4 c5
16 1 2 16 3
16 1 2 17 2
16 1 2 18 1
E avevo bisogno:
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
Ho risolto che con l'espressione:
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;
Se ti sto comprensione, si desidera un elenco di numeri consequtive?
Basta fare l'elenco:
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
... ecc, fino ad avere, diciamo, 1024.
update artificial_range set idn = id - 1 ;
- ora avete una serie fissando 1 (id) e una serie a partire da 0
Ora aderire ad esso, o partecipare alla trasformazione di esso:
create view days_this_century as
select date_add('2000-01-01', interval a.idn day) as cdate
from artificial_range;
Non so se questo aiuta, ma è possibile numerare le righe di ogni istruzione SELECT con qc. come:
SET @NUM = 0;
Seleziona @NUM: = @ NUM + 1 RowNumber, * FROM ...
E poi unirsi a loro su questo. A grandi database questo può essere molto lento.
Per generare 10 righe:
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
È possibile generare 100 righe fare un join con altri 10 righe:
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
E poi 1000 righe con un altro unirsi, ...