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


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 dual이 dual테이블에 실제로 액세스하지 않아서 편집의 질문에 대답합니다 (새로운 질문 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.