Как мне сделать генератор строк в MySQL? - PullRequest
20 голосов
/ 31 марта 2009

Есть ли способ создать произвольное количество строк, которые можно использовать в JOIN, аналогично синтаксису Oracle:

SELECT LEVEL FROM DUAL CONNECT BY LEVEL<=10

Ответы [ 7 ]

25 голосов
/ 01 апреля 2009

Ненавижу это говорить, но MySQL является единственным RDBMS из большой четверки, у которого нет этой функции.

В Oracle:

SELECT  *
FROM    dual
CONNECT BY
        level < n

В MS SQL (до 100 строк):

WITH hier(row) AS
        (
        SELECT  1
        UNION ALL
        SELECT  row + 1
        FROM    hier
        WHERE   row < n
        )
SELECT  *
FROM    hier

или с помощью подсказки до 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

В PostgreSQL:

SELECT  *
FROM    generate_series (1, n)

В MySQL, ничего.

13 голосов
/ 30 сентября 2013

В MySql я понимаю, что вы можете получить более одной строки с помощью SELECT без таблицы (или DUAL).

Поэтому, чтобы получить несколько строк, вам нужно нужна реальная или временная таблица с как минимум необходимым количеством строк.

Однако, вам не нужно создавать временную таблицу , так как вы можете использовать ANY существующую таблицу, в которой есть как минимум необходимое количество строк. Итак, если у вас есть таблица с как минимум необходимым количеством строк, используйте:

SELECT  @curRow := @curRow + 1 AS row_number
FROM    sometable 
JOIN    (SELECT @curRow := 0) r
WHERE   @curRow<100;

Просто замените «sometable» именем любой вашей таблицы, по крайней мере, с необходимым количеством строк.

PS: "r" - это таблица "псевдоним": я мог бы использовать "AS r". Любой подзапрос в предложении FROM или JOIN создает «производную таблицу», которая, как и во всех таблицах, должна иметь имя или псевдоним. (См. Руководство MySql: 13.2.9.8. Подзапросы в предложении FROM)

4 голосов
/ 23 марта 2018

Так как в настоящее время это один из первых результатов в Google для "mysql row generator", я добавлю обновление.

Если ваш вкус MySQL оказался MariaDB, у них есть эта функция. Он называется «Механизм хранения последовательности» и используется следующим образом:

select * from seq_1_to_10;

С результатами:

+-----+
| seq |
+-----+
|   1 |
|   2 |
|   3 |
|   4 |
|   5 |
|   6 |
|   7 |
|   8 |
|   9 |
|  10 |
+-----+
10 rows in set (0.00 sec)

До версии 10.0 это был отдельный плагин, который нужно было явно установить, но начиная с 10.0 он встроен. Наслаждайтесь!

2 голосов
/ 21 октября 2015

У меня была таблица со столбцом (c5), содержащая число x, мне нужно выражение SQL, которое повторяло одну и ту же строку x раз.

Мой стол А содержал:

c1  c2  c3  c4  c5
16  1   2   16  3
16  1   2   17  2 
16  1   2   18  1

И мне нужно было:

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

Я решил это с помощью выражения:

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;
1 голос
/ 02 апреля 2009

Если я вас понимаю, вы хотите список последовательных чисел?

Просто составьте список:

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

... и т. Д., Пока у вас не будет, скажем, 1024.

update artificial_range set idn = id - 1 ; 

- теперь у вас есть серия, начинающаяся с 1 (id), и серия, начинающаяся с 0

Теперь присоединитесь к нему или присоединитесь к его преобразованиям:

    create view days_this_century as 
select date_add('2000-01-01', interval a.idn day) as cdate 
from artificial_range;
0 голосов
/ 08 февраля 2019

Для генерации 10 строк:

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

Вы можете сгенерировать 100 строк, создавая соединение еще с 10 строками:

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

А затем 1000 строк с другим соединением, ...

0 голосов
/ 01 апреля 2009

Я не знаю, помогает ли это, но вы можете нумеровать строки из каждого оператора select с помощью sth. как:

SET @NUM = 0;

SELECT @NUM: = @ NUM + 1 rowNumber, * FROM ...

А позже присоединяйтесь к ним в этом. В больших базах данных это может быть очень медленно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...