에서 행으로 다양한 숫자를 얻는 것이 매우 어렵다는 것을 알았습니다 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
하고 코드를 축소하는 방법을 찾고 피곤 합니다.
MySQL이나 SQL 구문에서 골프를 하는 방법 (예 : 0-1,000,000 범위)에 대한 아이디어가 있습니까?
추가 포인트 가 제공됩니다 :
- 단일 진술
- 절차 없음
- 변수 없음
- DDL 문 없음
- DQL 문만
답변
sqlite와 같은 재귀 CTE 를 지원하는 SQL 언어의 경우 다음과 같은 작업을 수행 할 수 있습니다.
WITH RECURSIVE f(x) AS
(
SELECT 1 UNION ALL SELECT x + 1 FROM f LIMIT 1000000
)
SELECT x
FROM f;
기존 테이블에 의존하지 않으며 원하는대로 LIMIT 절을 변경할 수 있습니다. 원래 StackOverflow에서 변형을 보았습니다.
답변
@BradC의 방법과 유사합니다 .
테이블 [master]
범위가 -1에서 2048 사이 인 MS SQL 을 사용했습니다. BETWEEN
연산자를 사용하여 범위를 만들 수 있습니다.
SELECT DISTINCT(number)
FROM master..[spt_values]
WHERE number BETWEEN 1 AND 5
이 골프를하고 싶다면, 당신은 할 수 있습니다 :
SELECT TOP 5 ROW_NUMBER()OVER(ORDER BY number)FROM master..spt_values
답변
PostgreSQL, 35 바이트
PostgreSQL은 다음과 같이 쉽습니다.
SELECT * FROM generate_series(1,5)
이름이 필요한 경우 :
SELECT num FROM generate_series(1,5)AS a(num)
타임 스탬프를 사용하여이 작업을 수행 할 수도 있습니다. https://www.postgresql.org/docs/9.5/static/functions-srf.html
답변
이 게시물의 훌륭한 옵션 (@Arnauld가 제공) :
SELECT id%1000001 as num
FROM <any_large_table>
GROUP BY num
나를 위해-그것은 거의 도전을 해결합니다.
답변
PostgreSQL 관련
generate_series()
집합을 생성하므로 in from
절뿐만 아니라 집합이 발생할 수있는 곳이라면 어디에서나 사용할 수 있습니다.
psql=# select generate_series(10, 20, 3);
generate_series
-----------------
10
13
16
19
(4 rows)
세트에서 직접 작업을 수행 할 수도 있습니다.
psql=# select 2000 + generate_series(10, 20, 3) * 2;
?column?
----------
2020
2026
2032
2038
(4 rows)
여러 세트의 길이가 동일한 경우 병렬로 트래버스 할 수 있습니다.
psql=# select generate_series(1, 3), generate_series(4, 6);
generate_series | generate_series
-----------------+-----------------
1 | 4
2 | 5
3 | 6
(3 rows)
길이가 다른 세트의 경우 직교 곱이 생성됩니다.
psql=# select generate_series(1, 3), generate_series(4, 5);
generate_series | generate_series
-----------------+-----------------
1 | 4
2 | 5
3 | 4
1 | 5
2 | 4
3 | 5
(6 rows)
그러나 from
절 에서 사용하면 동일한 길이 세트에 대해 직교 곱을 얻습니다.
psql=# select * from generate_series(1, 2), generate_series(3, 4) second;
generate_series | second
-----------------+--------
1 | 3
1 | 4
2 | 3
2 | 4
(4 rows)
타임 스탬프 세트를 생성 할 수도 있습니다. 예를 들어 2000-06-30에 태어 났으며 주말에 생일을 몇 년 동안 축하했는지 알고 싶습니다.
psql=# select to_char(generate_series, 'YYYY - Day') from generate_series('2000-06-30', current_date, interval '1 year') where to_char(generate_series, 'D') in ('1', '7');
to_char
------------------
2001 - Saturday
2002 - Sunday
2007 - Saturday
2012 - Saturday
2013 - Sunday
(5 rows)
답변
MS SQL에는 master
데이터베이스 에 문서화되지 않은 시스템 테이블이 있습니다 spt_values
. 무엇보다도 0에서 2047까지의 숫자 범위가 포함됩니다.
--returns 0 to 2,047
SELECT number n
FROM master..spt_values
WHERE TYPE='P'
숫자 테이블로만 유용하지만 CTE에서는 큰 숫자를 매우 빠르게 얻을 수 있습니다.
--returns 0 to 4,194,304
WITH x AS(SELECT number n FROM master..spt_values WHERE TYPE='P')
SELECT 2048*x.a+*y.a
FROM x,x y
ORDER BY 1
답변
(이것은 MS-SQL에서 작동하지만 mySQL 또는 다른 플랫폼에서 작동하는지 확실하지 않습니다.)
더 작은 세트 (정렬 또는 비 정렬)의 경우 VALUES
생성자를 사용하십시오 .
--Generates 0-9
SELECT a
FROM(VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9))x(a)
(이것은 모든 반복 작은 따옴표로 문자열이 꽤 길어질 수 있지만 무엇이든 작동합니다.)
그런 다음 명명 된 CTE (공통 테이블 표현식)를 사용하여 교차 곱할 수 있으므로 반복하지 않아도됩니다.
--Generates 0-999
WITH x AS(SELECT a FROM(VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9))x(a))
SELECT 100*x.a+10*y.a+z.a
FROM x,x y,x z
ORDER BY 1
다른 많은 기술이 있습니다. 대부분의 경우 골프에 최적화되지 않았지만 “숫자 테이블 생성 SQL”을 찾으십시오.