상수로 채워진 여러 행을 선택하는 방법은 무엇입니까?


176

테이블을 참조하지 않고 상수를 선택하는 것은 SQL 문에서 완벽하게 합법적입니다.

SELECT 1, 2, 3

후자가 리턴하는 결과 세트는 값을 포함하는 단일 행입니다. 상수 표현식을 사용하여 한 번에 여러 행을 선택할 수있는 방법이 있는지 궁금합니다.

SELECT ((1, 2, 3), (4, 5, 6), (7, 8, 9))

위와 같이 작동하고 3 행과 3 열로 결과 집합을 반환하려고합니다.


1
위에서 상상 한 구문은 공식 구문보다 더 예쁘고 (INSERT INTO와 더 일관성이 있습니다). 말해봐
Pete Alvin

2
@PeteAlvin 상상 된 구문은 이미 Postgres에서 의미를 갖습니다 (튜플이있는 단일 행이 선택됨).
Kirill Bulygin

2
아래의 SQL Server 답변은 SQL Server에 잘 작동 하며이 구문과 거의 일치합니다. stackoverflow.com/a/53269562/2129481
BenPen

답변:


203
SELECT 1, 2, 3
UNION ALL SELECT 4, 5, 6
UNION ALL SELECT 7, 8, 9

2
나는 SQL Server와이 사용하고 일했다,하지만 난 사용했다 AS처음에 별명을주고SELECT
썰매

@ArtB에게 감사합니다.이 의견은 다른 개발자가 올바른 구문을 얻는 데 도움이 될 수 있습니다
Dewfy

3
또한 Oracle APEX 5.1에서 완벽하게 작동 Classic Report하여 정적 컨텐츠가있는 테이블 을 작성합니다 ( FROM dualSELECT값 이후 및 UNION ALL존재하는 경우).
VELFR

118

에서은 PostgreSQL, 당신은 할 수 있습니다 :

SELECT  *
FROM    (
        VALUES
        (1, 2),
        (3, 4)
        ) AS q (col1, col2)

다른 시스템에서는 다음을 사용하십시오 UNION ALL.

SELECT  1 AS col1, 2 AS col2
-- FROM    dual
-- uncomment the line above if in Oracle
UNION ALL
SELECT  3 AS col1, 3 AS col2
-- FROM    dual
-- uncomment the line above if in Oracle

이어 Oracle, SQL ServerPostgreSQL, 또한 행 (외부 변수 제공 가능한) 임의의 수의 레코드를 생성 할 수있다 :

SELECT  level
FROM    dual
CONNECT BY
        level <= :n

에서 Oracle,

WITH    q (l) AS
        (
        SELECT  1
        UNION ALL
        SELECT  l + 1
        FROM    q
        WHERE   l < @n
        )
SELECT  l
FROM    q
-- OPTION (MAXRECURSION 0)
-- uncomment line above if @n >= 100

에서 SQL Server,

SELECT  l
FROM    generate_series(1, $n) l

에서 PostgreSQL.


1
내가 가진 (약간 다른) 질문에 대답하기 위해 +1 : SELECT 1Oracle 에서 수행하는 방법 ( SELECT 1 FROM Dual작동).
Aasmund Eldhuset

13

VALUESPostgreSQL에서 다음과 같은 베어 명령이 작동합니다.

VALUES (1,2,3), (4,5,6), (7,8,9)

1
T-SQL에서도 다중 행 삽입 절로 작동합니다. 테이블 변수 또는 임시 테이블에 먼저 삽입하면 작동하지만 여러 단계가 가능합니다.
brianary

12

오라클에서 connect by 절을 사용해보십시오.

select level,level+1,level+2 from dual connect by level <=3;

connect by 절에 대한 자세한 내용을 보려면 다음 링크를 따르십시오. oraclebin 사이트가 이제 악성이므로 URL을 제거했습니다.


8

Microsoft SQL Server 또는 PostgreSQL의 경우이 구문을 사용해 볼 수 있습니다

SELECT constants FROM (VALUES ('foo@gmail.com'), ('bar@gmail.com'), ('baz@gmail.com')) AS MyTable(constants)

여기에서 SQL Fiddle을 볼 수도 있습니다. http://www.sqlfiddle.com/#!17/9eecb/34703/0


1
여러 열도 : 상수 상수, 이메일 FROM (VALUES (1, 'foo @ gmail.com'), (2, 'bar @ gmail.com'), (3, 'baz @ gmail .com ')) AS MyTable (constants, email)
BenPen

7

신탁. 이 게시물 덕분에 PL / SQL-절의 "목록"변수 사용

예제 문장을 정리하여 수동으로 값을 쉽게 입력 할 수 있습니다 (테스터가 응용 프로그램을 테스트 할 때 재 사용됨).

WITH prods AS (
    SELECT column_value AS prods_code 
    FROM TABLE(
        sys.odcivarchar2list(
            'prod1', 
            'prod2'
        )
    )
)
SELECT * FROM prods

1
이것은 생명의 은인이었습니다. 한 가지주의 할 점 : 너무 많은 값 오류가 발생하면 WITH 절에서 UNION ALL을 수행하면됩니다.
ScrappyDev


4

깔끔한 XML 트릭을 사용하여 Oracle 10 이상에서 정적 데이터를 채우는 방법은 다음과 같습니다.

create table prop
(ID NUMBER,
 NAME varchar2(10),
 VAL varchar2(10),
 CREATED timestamp,
 CONSTRAINT PK_PROP PRIMARY KEY(ID)
);

merge into Prop p
using (
select 
  extractValue(value(r), '/R/ID') ID,
  extractValue(value(r), '/R/NAME') NAME,
  extractValue(value(r), '/R/VAL') VAL
from
(select xmltype('
<ROWSET>
   <R><ID>1</ID><NAME>key1</NAME><VAL>value1</VAL></R>
   <R><ID>2</ID><NAME>key2</NAME><VAL>value2</VAL></R>
   <R><ID>3</ID><NAME>key3</NAME><VAL>value3</VAL></R>
</ROWSET>
') xml from dual) input,
 table(xmlsequence(input.xml.extract('/ROWSET/R'))) r
) p_new
on (p.ID = p_new.ID)
when not matched then
insert
(ID, NAME, VAL, CREATED)
values
( p_new.ID, p_new.NAME, p_new.VAL, SYSTIMESTAMP );

병합은 원본 테이블에서 누락 된 행만 삽입하므로 삽입 스크립트를 다시 실행하려는 경우 편리합니다.


3

DB2의 옵션 :

SELECT 101 AS C1, 102 AS C2 FROM SYSIBM.SYSDUMMY1 UNION ALL
SELECT 201 AS C1, 202 AS C2 FROM SYSIBM.SYSDUMMY1 UNION ALL
SELECT 301 AS C1, 302 AS C2 FROM SYSIBM.SYSDUMMY1

0

오라클에서

SELECT
  CASE
    WHEN level = 1
    THEN 'HI'
    WHEN level = 2
    THEN 'BYE'
  END TEST
FROM dual
  CONNECT BY level <= 2;

0

다음은 DB2의 XML 기능을 사용하여 수행하는 방법입니다.

SELECT *
FROM
XMLTABLE ('$doc/ROWSET/ROW' PASSING XMLPARSE ( DOCUMENT '
<ROWSET>
  <ROW>
    <A val="1" /> <B val="2" /> <C val="3" />
  </ROW>
  <ROW>
    <A val="4" /> <B val="5" /> <C val="6" />
  </ROW>
  <ROW>
    <A val="7" /> <B val="8" /> <C val="9" />
  </ROW>
</ROWSET>
') AS "doc"
   COLUMNS 
      "A" INT PATH 'A/@val',
      "B" INT PATH 'B/@val',
      "C" INT PATH 'C/@val'
) 
AS X
;

0

이 방법은 당신을 도울 수 있습니다

SELECT   TOP 3
         1 AS First, 
         2 AS Second, 
         3 AS Third 
FROM     Any_Table_In_Your_DataBase

Any_Table_In_Your_DataBase:3 개 이상의 레코드가 포함 된 테이블 또는 시스템 테이블을 사용합니다. 여기서 우리는 해당 테이블의 데이터에 관심이 없습니다.

열을 Any_Table_In_Your_DataBase테이블의 첫 번째, 두 번째 및 세 번째 열과 연결하여 결과 집합의 변형을 가져올 수 있습니다 .


사용할 데이터베이스를 지정해야합니다. 'TOP'키워드는 Oracle에서 작동하지 않습니다.
Hans Deragon

0

MySQL에서는 다음을 수행 할 수 있습니다. values (1,2), (3, 4);

mysql> values (1,2), (3, 4);
+---+---+
| 1 | 2 |
+---+---+
| 1 | 2 |
| 3 | 4 |
+---+---+
2 rows in set (0.004 sec)

MySQL 8을 사용하면 열 이름을 지정할 수도 있습니다.

mysql> SELECT * FROM (SELECT 1, 2, 3, 4) AS dt (a, b, c, d);
+---+---+---+---+
| a | b | c | d |
+---+---+---+---+
| 1 | 2 | 3 | 4 |
+---+---+---+---+

1
"values ​​(1,2), (3, 4);"에 대해 어떤 버전의 mysql이 있습니까?
Rene Wooller

그 두 번째 예는 실제로 여러 행을 계속 선택합니까? 또한 그들 중 어느 것도 PhpMyAdmin에서 쿼리로 실행되지 않는 것 같습니다. 어떤 MySQL 버전을 사용하고 있는지 알 수 있기를 원하지만 MySQL 버전이 너무 혼란 스럽기 때문에 알아낼 때까지 확신합니다. 이 의견을 편집 할 시간이 없습니다 ...
still_dreaming_1

0
select (level - 1) * row_dif + 1 as a, (level - 1) * row_dif + 2 as b, (level - 1) * row_dif + 3 as c
    from dual 
    connect by level <= number_of_rows;

그런 것

select (level - 1) * 3 + 1 as a, (level - 1) * 3 + 2 as b, (level - 1) * 3 + 3 as c
    from dual 
    connect by level <= 3;
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.