Подтвердить что ты не робот

SQL SELECT, чтобы получить первые N положительных целых чисел

Мне нужно получить набор результатов, содержащий первые N положительных целых чисел. Можно ли использовать только стандартный оператор SQL SELECT для их получения (без какой-либо таблицы счетчиков)?

Если это невозможно, существует ли какой-либо конкретный способ MySQL для этого?

4b9b3361

Ответ 1

Кажется, что вы хотите dummy rowset.

В MySQL невозможно без таблицы.

Большинство основных систем обеспечивают способ сделать это:

  • В Oracle:

    SELECT  level
    FROM    dual
    CONNECT BY
            level <= 10
    
  • В SQL Server:

    WITH    q AS
            (
            SELECT  1 AS num
            UNION ALL
            SELECT  num + 1
            FROM    q
            WHERE   num < 10
            )
    SELECT  *
    FROM    q
    
  • В PostgreSQL:

    SELECT  num
    FROM    generate_series(1, 10) num
    

MySQL не хватает чего-то подобного, и это серьезный недостаток.

Я написал простой script для генерации тестовых данных для таблиц примеров в своих сообщениях в блоге, возможно, это будет полезно:

CREATE TABLE filler (
        id INT NOT NULL PRIMARY KEY AUTO_INCREMENT
) ENGINE=Memory;

CREATE PROCEDURE prc_filler(cnt INT)
BEGIN
        DECLARE _cnt INT;
        SET _cnt = 1;
        WHILE _cnt <= cnt DO
                INSERT
                INTO    filler
                SELECT  _cnt;
                SET _cnt = _cnt + 1;
        END WHILE;
END
$$

Вы вызываете процедуру, и таблица заполняется цифрами.

Вы можете повторно использовать его во время сеанса.

Ответ 2

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

Для первых 10 целых чисел (используя mysql.help_relation, но любая таблица будет делать), вы можете использовать следующий запрос:

SELECT  @N := @N +1 AS integers 
FROM mysql.help_relation , (SELECT @N:=0) dum LIMIT 10;

Это также может быть помещено в функцию, принимающую Min и Max.

Ответ 3

Странное решение, но...

SELECT 1 UNION SELECT 2 UNION SELECT 3....

Ответ 4

Предполагая, что вы хотите получить их из таблицы, здесь N равно 10, если intcolumn - столбец с числами в нем.

SELECT intcolumn FROM numbers WHERE intcolumn > 0 LIMIT 10

Изменить. Если бы вы действительно искали математический набор положительных чисел без таблицы, я бы пересмотрел ее, это может быть интенсивным (в зависимости от реализации). Обычно принятая практика состоит в том, чтобы создать таблицу поиска, заполненную числами, и затем использовать указанный выше запрос.

Ответ 5

Последовательность, которую я предлагаю, позволяет программисту выполнить следующий запрос:

select value from sequence where value>=15 and value<100;

И для получения ожидаемых результатов: последовательность целых чисел между 15 (включительно) и 100 (исключая).

Если это вам нужно, вам нужно будет создать два следующих вида, представления, которые вы будете объявлять только один раз:

create view digits as select 0 n 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;

create view sequence as select u.n+t.n*10+h.n*100 as value from digits as u cross join digits as t cross join digits as h;

Таким образом, у вас есть последовательность с интуитивным SELECT...

Надеюсь, что это поможет.

Ответ 6

Это может помочь

Чтобы получить случайное целое число R в диапазоне я <= R < j, используйте выражение FLOOR (i + RAND() * (j - i)). Например, чтобы получить случайное целое число в диапазоне, диапазон 7 <= R < 12, вы можете использовать следующее утверждение:

SELECT FLOOR(7 + (RAND() * 5));

Ответ 7

Если вы знаете, что N ограничен (и обычно это так), вы можете использовать такую ​​конструкцию, как:

select (a.digit + (10 * b.digit) + (100 * c.digit) + (1000 * d.digit) + (10000 * e.digit) + (100000 * f.digit)) as n
    from (select 0 as digit 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) as a
    cross join (select 0 as digit 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) as b
    cross join (select 0 as digit 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) as c
    cross join (select 0 as digit 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) as d
    cross join (select 0 as digit 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) as e
    cross join (select 0 as digit 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) as f;

который будет генерировать первые миллионы чисел. Если вам нужны только положительные числа, просто добавьте + 1 в выражение.

Обратите внимание, что в MySQL, в частности, результаты могут не сортироваться. Вам нужно добавить order by n в конец, если вам нужны упорядоченные номера. Это значительно увеличит время выполнения, хотя (на моей машине он вскочил с 5 мс до 500 мс).

Для простых запросов здесь запрос только для первых 10000 номеров:

select (a.digit + (10 * b.digit) + (100 * c.digit) + (1000 * d.digit)) as n
    from (select 0 as digit 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) as a
    cross join (select 0 as digit 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) as b
    cross join (select 0 as digit 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) as c
    cross join (select 0 as digit 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) as d;

Этот ответ адаптирован из следующего запроса, который возвращает диапазон дат: fooobar.com/questions/8819/...

Ответ 8

Взгляните на следующие вопросы SO:

Edit:

Еще один пример - создать хранимую процедуру, которая сделает это за вас. PostgreSQL содержит функцию generate_series (start, stop), которая делает то, что вы хотите.

select * from generate_series(2,4);
 generate_series
-----------------
               2
               3
               4
(3 rows)

Я не знакомы с MySQL, но что-то вроде этого должно быть легко реализовать, если вы в порядке с SP. Этот сайт демонстрирует завершение.

Ответ 9

Я уверен, что вы не сможете этого сделать, если я правильно понял ваш вопрос.

Насколько я понимаю ваш вопрос, вам нужен список из одного оператора SQL без ссылки на конкретную таблицу?

Я уверен, что это невозможно на любом диалекте SQL. Если бы вы получили последовательно увеличивающееся число вместе с результатами другого запроса, тогда это было бы возможно (в зависимости от диалекта SQL, на mssql это был бы rownumber(), но я не знаю, как в MySql, но он, вероятно, есть)

Но это не то, что я слышу, вы спрашиваете?

Ответ 10

Если ваша база данных поддерживает аналитические функции окон, то следующие простые работы очень хорошо:

SELECT  row_number() over (partition by 1 order by 1) numbers
FROM SOME_TABLE
LIMIT 2700;

Этот оператор возвращает набор чисел от 1 до 2700.