Мне было довольно сложно достичь диапазона чисел в виде строк MySQL
.
Например, диапазон 1-5 достигается путем:
SELECT 1
UNION
SELECT 2
UNION
SELECT 3
UNION
SELECT 4
UNION
SELECT 5
приведет к:
1 2 3 4 5
для 0-99 я могу соединить две таблицы 0-9:
CREATE TABLE nums as
SELECT 0 as num
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
;
Select n.num*10+nums.num v
From nums n cross join nums
Я устал писать все это UNION
и искать способ уменьшить код.
Любые идеи, как играть в гольф (например, диапазон 0-1 000 000) в MySQL или любой синтаксис SQL?
Дополнительные баллы начисляются за:
- одно заявление
- нет процедур
- без переменных
- нет заявлений DDL
- только операторы DQL
generate_series()
. У нас есть несколько примеров использования здесь.Ответы:
Для диалектов SQL, которые поддерживают рекурсивные CTE, такие как sqlite, вы можете сделать что-то вроде следующего:
Это не зависит от какой-либо существующей таблицы, и вы можете изменить предложение LIMIT по желанию. Первоначально я видел вариант этого на StackOverflow.
источник
WITH t AS(SELECT 1n UNION ALL SELECT n+1FROM t WHERE n<36)SELECT n FROM t
Для разных конечных точек просто измените1
и36
на то, что вы хотите.option (maxrecursion 0)
в конец вышеприведенного оператора, в противном случае произойдет ошибка при рекурсии свыше 100. (Либо установитеmaxrecursion
конкретное значение, либо 0, чтобы разрешить бесконечность) ,Похоже на метод @ BradC .
Я использовал MS SQL, в котором есть таблица
[master]
с диапазоном чисел от -1 до 2048. Вы можете использоватьBETWEEN
оператор для создания своего диапазона.Если вы хотите играть в гольф, вы можете сделать:
источник
WHERE number>0AND number<21
SELECT DISTINCT(number+2)... WHERE number<19
PostgreSQL, 35 байт
В PostgreSQL это просто:
Если вам нужно это имя:
Вы также можете сделать это с отметками времени. https://www.postgresql.org/docs/9.5/static/functions-srf.html
источник
Отличный вариант из этого поста (найден @Arnauld):
Для меня - это в значительной степени решает проблему.
источник
id
поле, заполненное очень большими значениями. Это довольно специфично для базы данных, и вы можете пропустить строку, если, скажем, кто-то удалит ID продукта = 4021.Специфичный для PostgreSQL
generate_series()
генерирует набор, так что вы можете использовать его не только вfrom
предложении, но и везде, где может происходить набор:Вы также можете выполнять операции непосредственно на съемочной площадке:
Если несколько наборов имеют одинаковую длину, вы можете пройти их параллельно:
Для наборов различной длины генерируется декартово произведение:
Но если вы используете их в
from
предложении, вы получите декартово произведение для наборов одинаковой длины:Он также может генерировать множество временных меток. Например, вы родились 2000-06-30 и хотите знать, в какие годы вы отмечали свой день рождения на выходных:
источник
MS SQL имеет недокументированную системную таблицу в
master
базе данныхspt_values
. Среди прочего, он содержит диапазон чисел от 0 до 2047:Полезно в качестве таблицы чисел само по себе, но в CTE вы можете довольно быстро получить несколько больших чисел:
источник
(Они работают в MS-SQL, не уверен, работают ли они для mySQL или других платформ.)
Для небольших наборов (упорядоченных или не упорядоченных) используйте
VALUES
конструктор:(Это работает для чего угодно, хотя строки могут быть довольно длинными со всеми повторяющимися одинарными кавычками.)
Затем вы можете кросс-умножить, используя именованное CTE (общее табличное выражение), так что вам не нужно его повторять:
Есть множество других методов, ищите «SQL, генерирующий таблицу чисел», хотя большинство не оптимизировано для игры в гольф.
источник
limit Y
чтобы сделать произвольные диапазоны?SELECT TOP 250 ...
Еще одна опция, специфичная для MS SQL 2016 и выше:
Я, вероятно, нахожу это более удобным для списков строк, но я вижу способы, которые это будет полезно и с числами.
источник
T-SQL, 98 байт
источник
Еще один для SQL Server ...
источник