Как создать (фиктивный) столбец произвольной длины с помощью MonetDB?

Я хотел бы запустить эквивалент PostgreSQL

SELECT * FROM GENERATE_SERIES(1, 10000000)

Я прочитал это:

http://blog.jooq.org/2013/11/19/how-to-create-a-range-from-1-to-10-in-sql/

Но большинство предложений на самом деле не имеют произвольной длины - запрос зависит от длины иначе, чем просто заменой числа. Кроме того, некоторые предложения не применяются в MonetDB. Итак, каков мой лучший план действий (если есть)?

Примечания. Я использую версию от февраля 2013 года. Также приветствуются ответы о новых функциях, но это именно то, что мне нужно. - Предположим, что в существующих таблицах недостаточно строк; и не предполагайте, что, скажем, декартово произведение самой длинной таблицы на себя достаточно (или, наоборот, может быть, это слишком дорого для выполнения).


person einpoklum    schedule 01.06.2014    source источник
comment
Не знаком с MonetDB, но похоже, что кто-то передал generate_series функцию в исходный код две недели назад. Можете ли вы построить из исходного кода и использовать это?   -  person Iain Samuel McLean Elder    schedule 01.06.2014
comment
@IainElder: отредактировано для решения этой проблемы.   -  person einpoklum    schedule 01.06.2014
comment
Что вы собираетесь делать со значениями? Если вам нужно использовать 10 миллиардов последовательных значений в качестве первичного ключа, есть лучшие способы генерировать значения. Дайте немного больше контекста, чтобы мы могли помочь вам лучше.   -  person Iain Samuel McLean Elder    schedule 01.06.2014


Ответы (2)


Попробуйте с:

SELECT value
FROM sys.generate_series(initial_value, end_value, offset);

Я должен сообщить, что эта функция довольно нестабильна в выпуске от июля 2015 года, так как вызывает сбой серверного процесса. Надеюсь, тебе повезет больше.

Если вы хотите сгенерировать произвольное числовое значение, вы можете использовать:

SELECT rand();
person Vincenzo Grimaldi    schedule 01.09.2015
comment
Итак, вы говорите, что это новая функция версии от июля 2015 года? Или он просто стал нестабильным в последнее время? - person einpoklum; 02.09.2015
comment
Нет, он доступен и в предыдущих выпусках, иногда выглядит нестабильно, но может быть из-за ограничения памяти моего экземпляра. - person Vincenzo Grimaldi; 03.09.2015

Простите меня; Я никогда раньше не работал с MonetDB. Но документация заставляет меня поверить, что вы можете решить эту проблему с помощью функции ROW_NUMBER и предварительно заполненная таблица, такая как SYS.COLUMNS.

SELECT ROW_NUMBER() OVER () AS rownum
FROM SYS.COLUMNS;

Это попадает в категорию jooq.org просто брать случайные записи из «достаточно большой» таблицы.

Функция PostgreSQL generate_series элегантна, но нестандартна. Он отсутствует в других основных механизмах, таких как SQL Server, Oracle и MySQL. В вашей версии MonetDB его тоже нет.

В MonetDB есть функция ROW_NUMBER, близкий эквивалент в стандартный SQL. Он присваивает последовательное целое число строкам в результирующем наборе. Он выведет правильные значения, но ему уже нужны некоторые строки в вашей базе данных. Проблема курицы и яйца!

SYS.COLUMNS — это системная таблица метаданных, содержащая по одной строке для каждого столбца в вашей базе данных. Большинство «пустых» реляционных баз данных по-прежнему имеют сотни системных столбцов, которые появляются в таких таблицах.

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

SELECT rownum
FROM (
  SELECT ROW_NUMBER() OVER () AS rownum
  FROM SYS.COLUMNS
) AS tally
WHERE rownum >= 1 AND rownum <= 10;

Но что, если вам нужно сгенерировать больше строк, чем есть в SYS.COLUMNS? К сожалению, форма запроса зависит от того, сколько строк вы хотите сгенерировать.

Распространенным обходным решением в сообществе Microsoft SQL Server было бы присоединение SYS.COLUMNS к самому себе. Это создаст промежуточную таблицу, содержащую квадрат числа строк в таблице. На практике это, вероятно, больше строк, чем вам когда-либо понадобится.

С самообъединением решение выглядит так:

SELECT rownum
FROM (
  SELECT ROW_NUMBER() OVER () AS rownum
  FROM SYS.COLUMNS AS a, SYS.COLUMNS AS b
) AS tally
WHERE rownum >= 1 AND rownum <= 100000;

Надеюсь, эти запросы актуальны и в мире MonetDB!

person Iain Samuel McLean Elder    schedule 01.06.2014
comment
Да, это действительно так... однако я хочу, чтобы один и тот же запрос работал независимо от того, нужно ли мне сгенерировать 10 записей или 10 000 000 000. - person einpoklum; 01.06.2014
comment
Чтобы использовать только один запрос, заранее узнайте, сколько строк вам когда-либо понадобится, и количество строк в исходной таблице. Напишите запрос с минимальным количеством самосоединений, чтобы сгенерировать как минимум ваше максимальное число. Если вам никогда не требуется более 10 миллиардов строк, а исходная таблица содержит 1000 строк, вам нужен запрос, который ссылается на источник четыре раза. В цифрах 1000 ^ 3 < 10 billion < 1000 ^ 4. Если вы решите, что хотите еще больше, добавьте еще одно соединение. В конце концов у вас закончится время, место, деньги или терпение, чтобы обработать его, и к этому моменту он, вероятно, будет достаточно большим :-) - person Iain Samuel McLean Elder; 01.06.2014