2009-03-31 7 views
18

Esiste un modo per generare un numero arbitrario di file che possono essere utilizzati in un join simile alla sintassi Oracle:Come creare un generatore di righe in MySQL?

SELECT LEVEL FROM DUAL CONNECT BY LEVEL<=10 
+0

La prego di inviare la query si intende scrivere ? –

risposta

22

Odio dire questo, ma MySQL è l'unico RDBMS dei quattro grandi che non ha questa funzione.

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) 

Nel MySQL, niente.

+4

Reg MySQL: Spero che colmi un po 'il vuoto: http://use-the-index-luke.com/blog/2011-07-30/mysql -row-generator # mysql_generator_code –

0

Avete considerato un LEFT OUTER JOIN?

+1

Sì, il problema è che ho bisogno di qualcosa per fare il JOIN contro – GameFreak

0

Non so se questo aiuta ma è possibile numerare le righe da ciascuna istruzione select con sth. come:

SET @NUM = 0;

SELEZIONA @NUM: = @ NUM + 1 RowNumber, * FROM ...

E poi unirsi a loro su questo. In database di grandi dimensioni questo può essere molto lento.

0

Se ti capisco, vuoi una lista di numeri consecutivi?

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 unirsi 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; 
+3

era esattamente quello che speravo di evitare. – GameFreak

8

In MySql, è a mia conoscenza che è possibile ottenere più di una riga con una SELECT senza tabella (o DUAL).

Pertanto, per ottenere più righe, è necessario do una tabella reale o temporanea con almeno il numero richiesto di righe.

Tuttavia, non c'è bisogno di costruire una tabella temporanea come si può utilizzare QUALSIASI tabella esistente che ha almeno il numero di righe necessarie.Quindi, se si dispone di un tavolo con almeno il numero di righe, l'uso:

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: "r" è una tabella "alias": avrei potuto usare "AS r". Qualsiasi subquery in una clausola FROM o JOIN crea una "tabella derivata" che, come con tutte le tabelle, deve avere un nome o un alias. (Vedere il manuale MySql: 13.2.9.8 Sottorubriche nella clausola FROM)

0

Avevo una tabella con una colonna (c5) che conteneva un numero x, avevo bisogno di un'espressione SQL che ripetesse la stessa riga x numeri di volte.

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; 
Problemi correlati