듀얼 테이블에서 선택해야하는 이유는 무엇입니까?


15

이것은 SQL Server, MySQL, PostgreSQL 및 SQLite (WebSQL) 인 StackOverflow / dba.stackexchange에 나타날 가능성이 큰 주요 관계 데이터베이스 관리 시스템에서 작동합니다 .

select 'abc' abc, 1 def;

Oracle에서는 작동하지 않습니다. Oracle의 DUAL에서 왜 선택해야합니까? SQL에 대한 ISO / ANSI 표준에 SELECT 문에 FROM 절이 필요 합니까?


편집하다:

Bacon Bit의 대답, 그것은 SQL 표준에서 요구 보인다.

DUAL 이름 등의 잘못된이기 때문에 내가 있다면 그래서 현실에서, 테이블을 생성하고 원자의 이름 또는 하나에, 예를 들면 create table one (atom int);.. select 'abc' abc, 1 def FROM one;- 성능 저하는 비교가 있습니까 SELECT .. FROM DUAL?


나는 DB2도 없이는 할 수 없다고 생각select 한다 from. DB2에는 SYSIBM.SYSDUMMY1 이라는 유사한 더미 테이블이 있습니다 . 또한 당신은 이미 이것을 알고 있지만, 당신 select 'A' from dualdual테이블에 실제로 액세스하지 않아서 편집의 질문에 대답합니다 (새로운 질문 btw를 나타냅니다).
Jack은 topanswers.xyz를 5

1
"모든"DBMS 에서는 작동 하지 않습니다 . FROM없이 SELECT를 허용하지 않는 여러 DBMS가 있습니다. 설명서는 성능에 대한 귀하의 질문에 대한 답 : docs.oracle.com/cd/E11882_01/server.112/e26088/...
a_horse_with_no_name

3
@ JackDouglas : 맞습니다. DB2에는 FROM절이 필요합니다 . 내 머리 위로 : Informix, Firebird 및 Apache Derby도 필요합니다.
a_horse_with_no_name 7

1
DB2에는 FROM 절이 필요하지만 대안은 같은 명령문을 사용하는 것 values ('abc', 1)입니다. 당신은 또한 그러한 진술에서 선택할 수 있습니다 :select abc from ( values ('abc',1) ) as t(abc,def)
Lennart

답변:


30

엄밀히 말하자면, 문장 의 FROM절은 SELECT선택 사항이 아닙니다. SQL-99 구문 은 기본 SELECT문장을 자세히 설명 하고 FROM절에는 대괄호가 없습니다. 이는 표준이 선택 사항이 아닌 것으로 간주 함을 나타냅니다.

SELECT [ DISTINCT | ALL ]
{Column expression [ AS name ]} [ ,... ] | *
FROM <Table reference> [ {,<Table reference>} ... ]
[ WHERE search condition ]
[ GROUP BY Columns [ HAVING condition ] ]
[ORDER BY {col_name | expr | position} [ASC | DESC],...]                                     
[LIMIT {[offset,] row_count | row_count OFFSET offset}]
[PROCEDURE procedure_name(argument_list)]
[INTO OUTFILE 'file_name' export_options |
 INTO DUMPFILE 'file_name' |
 INTO var_name [, var_name]]
[FOR UPDATE | LOCK IN SHARE MODE]

실제 사용에서 프로그래머와 DBA는 종종 테이블의 데이터를 조작하거나 테이블과 데이터 구조를 조작하는 것 이외의 작업을 수행하는 것이 유용하다는 것을 알게됩니다. 이러한 유형의 작업은 SQL 표준의 범위를 크게 벗어나며 특정 구현의 기본 요소보다 더 많은 데이터 기능과 관련이 있습니다. 우리가 실행하려는 여부 SELECT getdate()SELECT 1또는 SELECT DB_NAME()(나 방언이 좋아 무엇이든), 우리는 실제로 테이블에서 데이터를 원하지 않는다.

오라클은 다음과 같은 효과적인 정의로 더미 테이블을 사용하여 표준 및 구현 불일치를 해결하기로 결정했습니다.

CREATE TABLE DUAL (
  DUMMY CHAR(1)
  )

INSERT INTO DUAL (DUMMY) VALUES ('X')

다른 RDBMS는 기본적으로 더미 테이블 FROM이 지정 되지 않은 경우 더미 테이블이 사용된다고 가정 합니다.

DUAL 테이블역사는 Wikipedia에 있습니다.

DUAL 테이블은 Oracle Corporation의 Charles Weiss가 내부보기에 참여하기위한 테이블을 제공하기 위해 작성했습니다.

Oracle Data Dictionary에서 DUAL 테이블을 기본 개체로 만들었습니다. 그 자체로 볼 수는 없었지만 쿼리가 예상되는 뷰 내부에서 사용되었습니다. 아이디어는 DUAL 테이블에 JOIN을 수행하고 테이블의 각 행마다 결과에 두 개의 행을 작성할 수 있다는 것입니다. 그런 다음 GROUP BY를 사용하여 결과 조인을 요약하여 DATA 익스텐트 및 INDEX 익스텐트의 스토리지 양을 표시 할 수 있습니다. DUAL이라는 이름은 단 하나의 행에서 한 쌍의 행을 작성하는 프로세스에 적합 해 보였습니다.

원래의 DUAL 테이블에는 두 개의 행이 있었으므로 (따라서 이름) 한 행만있었습니다.


3
+1하고 dba.se에 오신 것을 환영합니다. 이것은의 매력적인 비트와 훌륭한 답변입니다 역사 - 나는 당신이 곁에하도록 권장 할 수 있기를 희망하고 :) 더 많은 기여
잭은 말한다 topanswers.xyz 시도

4
개발자가 듀얼에 몇 줄을 더 삽입했을 때 한 시간 동안 끝없는 즐거움이있었습니다. 많은 것들을 파산 :) 범인을 추적하기 위해 시간이 걸렸습니다!
Philᵀᴹ

8

dual옵티마이 저가 이해 하는 이점 은 dual특별한 하나의 행, 하나의 열 테이블 ( varchar2데이터 유형)을 사용하는 것입니다. 쿼리에 사용할 때 계획을 개발할 때이 지식을 사용합니다.

dual오라클 에서 왜 선택해야 합니까?

당신은 dual당신이 원하는 경우에, 당신은 당신의 자신의 테이블에서 선택할 수 있습니다 .

나를 위해, 나는 존재한다는 dual것을 알고 있기 때문에 고집 할 것 dual입니다. 나는 그것이 적어도 1과 최대 1 행을 가지고 있음을 알고 있습니다. 최적화 프로그램이 모든 것을 알고 dual가장 효율적으로 수행한다는 것을 알고 있습니다. 옵티마이 저는 dual마법의 특수 1 행 테이블임을 이해 합니다. select *거기에 한 행이 있기 때문에 중지되었습니다 . 그것이 작동하는 방식입니다.


"나는 적어도 1 행에서 최대 1 행을 가지고 있다는 것을 안다." DBA 권한을 가진 바보 (또는 바보) 는 수정할 수 있습니다DUAL . 조심해!
Nick Chammas

그게 당신에게 일어난다면. 이 누군가의 CREATE SESSION을 제외한 모든 권한을 취소하십시오. 누군가가 실수로 듀얼을 떨어 뜨린 경우 어떻게해야합니까?
DevYudh

테이블 이중 생성 (더미 varchar2 (1)) 스토리지 (초기 1) 또는 플래시백 테이블을 삭제 전 이중으로 사용하여 생성 할 수 있습니다.
DevYudh

음, 기존의 다른 테이블에서 식을 선택에 비해 그것은 DUAL를 사용의 장점은, 그러나 그것은 PostgreSQL을 또는 SQLServer에에 같은 FROM이 필요하지에 대한 대안으로 DUAL을 갖는 장점이 무엇을 설명하지 않습니다
다뉴브 선원

Oracle의 @Lukasz Lech는 #MSSQL Serv에 대해 FROM이없는 SELECT가 없습니다. SQL Server에 이중 테이블이 필요하지 않습니다. 그러나 코드를 oracle에서 SQL Serv로 전송 한 경우이 스크립트 CREATE TABLE DUAL (DUMMY VARCHAR (1))을 사용하여 이중을 생성 할 수 있습니다. SQL Server에서 이중 테이블을 사용 / 생성하는 이유. 또한 MSSQL SERV와 PostGRE SQL은 더미 테이블을 필요로 해달라고
DevYudh

1

다른 두 답변은 내 답변에 좋은 배경을 제공합니다.

Oracle 데이터베이스에서는 전통적이고 신뢰할 수 있습니다. DUAL테이블 이없는 다른 데이터베이스에서는 실패 합니다. 를 사용할 필요는 없지만 DUAL권장합니다.

표준 호환 데이터베이스 FROM에는 적어도 테이블 참조를 지정 하는 절이 필요합니다 . ORDERS 테이블이있는 경우 다음 FROM DUAL절 대체 가 작동합니다.

FROM   orders
WHERE  rownum =1

선택할 수있는 테이블이나 뷰를 대체하면 작동합니다. 선택할 수없는 테이블이나 뷰를 대체하면 실패합니다. DUALDBA가이를 깨뜨리는 것을 막는 것이 더 안정적이며, 모든 사용자가 DBA를 선택할 수 있으며 결과 세트에서 단 하나의 행만 얻게됩니다. (때로는 고장납니다.)

테이블 참조를 포함하지 않고 테이블에없는 데이터에 액세스하기위한 표준 호환 동사를 인식하지 못합니다. 그러한 데이터에 액세스하는 데 필요한 양이 적기 때문에 그러한 요구가 보이지 않습니다. 내가 만나는 많은 사례는 다른 방식으로 더 잘 처리 될 수 있습니다.


2
SELECT CURRENT_TIMESTAMP FROM (VALUES(1)) V(C)내가 믿는 표준을 준수하며 특정 테이블에 의존하지 않습니다.
Martin Smith

@MartinSmith 테이블 참조를 사용하도록 응답을 업데이트했습니다. 이것이 내가 의미하고 지정한 것입니다.
BillThor
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.