Dlaczego muszę wybierać z podwójnego stołu?

15

Działa to w głównych systemach zarządzania relacyjnymi bazami danych, które najprawdopodobniej pojawiają się na StackOverflow / dba.stackexchange, tj. SQL Server, MySQL, PostgreSQL i SQLite (WebSQL) .

select 'abc' abc, 1 def;

To nie działa na Oracle. Dlaczego musimy wybierać spośród DUAL w Oracle? Czy standard ISO / ANSI dla SQL wymaga klauzuli FROM dla instrukcji SELECT ?


Edytować:

Według Bacon Bitodpowiedzi wydaje się, że jest to wymagane przez standard SQL.

Tak więc w rzeczywistości, ponieważ nazwa DUAL jest tak mylącą nazwą, gdybym miał stworzyć tabelę i nazwać ją ATOM lub JEDEN, np create table one (atom int);. select 'abc' abc, 1 def FROM one;- Czy w porównaniu z nią występuje utrata wydajności SELECT .. FROM DUAL?

孔夫子
źródło
Myślę, że DB2 również nie może zrobić selectbez from. DB2 ma podobną tabelę fikcyjną o nazwie SYSIBM.SYSDUMMY1 . Prawdopodobnie już to wiesz, ale kiedy tak naprawdę nie masz dostępuselect 'A' from dual do dualtabeli , co odpowiada na pytanie w twojej edycji (która zasługuje na nowe pytanie btw).
Jack mówi, że spróbuj topanswers.xyz
1
To ma nie pracować w „all” DBMS. Istnieje kilka DBMS, które nie pozwalają na SELECT bez FROM. Podręcznik odpowiada na twoje pytanie dotyczące wydajności: docs.oracle.com/cd/E11882_01/server.112/e26088/...
a_horse_with_no_name
3
@JackDouglas: Masz rację. DB2 wymaga FROMklauzuli. Z góry mojej głowy: Informix, Firebird i Apache Derby również tego wymagają.
a_horse_w_no_name
1
DB2 wymaga klauzuli FROM, ale alternatywą jest użycie instrukcji podobnej do values ('abc', 1). Możesz oczywiście również wybrać z takiego oświadczenia:select abc from ( values ('abc',1) ) as t(abc,def)
Lennart

Odpowiedzi:

30

Ściśle, tak, FROMklauzula SELECToświadczenia nie jest opcjonalna. Składnia SQL-99 wyszczególnia podstawowe SELECTzestawienie, a FROMklauzula nie zawiera nawiasów kwadratowych. Oznacza to, że standard uznaje go za nieobowiązkowy:

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]

W rzeczywistości, programiści i DBA często uważają, że przydatne jest wykonywanie innych czynności niż manipulowanie danymi w tabelach lub manipulowanie tabelami i strukturami danych. Tego rodzaju rzeczy w dużej mierze wykraczają poza zakres standardu SQL, który dotyczy danych więcej niż zwykłych implementacji. Czy chcemy uruchomić SELECT getdate()lub SELECT 1lub SELECT DB_NAME()(lub niezależnie od woli dialekt), to w rzeczywistości nie chcą dane z tabeli.

Oracle wybiera rozwiązanie rozbieżności między standardem a implementacją za pomocą tabeli zastępczej o następującej skutecznej definicji:

CREATE TABLE DUAL (
  DUMMY CHAR(1)
  )

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

Inne RDBMS zasadniczo zakładają, że używana jest tabela zastępcza, jeśli nie FROMokreślono nie.

Historia DUAL tabeli jest na Wikipedii:

Tabela DUAL została stworzona przez Charlesa Weissa z korporacji Oracle, aby zapewnić tabelę do łączenia w widokach wewnętrznych:

Stworzyłem tabelę DUAL jako podstawowy obiekt w Oracle Data Dictionary. Nigdy nie miał być widziany sam, ale zamiast tego użyty w widoku, który miał być zapytany. Pomysł polegał na tym, że można wykonać DOŁĄCZ do tabeli DUAL i utworzyć w wyniku dwa wiersze dla każdego wiersza w tabeli. Następnie, używając GROUP BY, powstałe sprzężenie może być podsumowane, aby pokazać ilość miejsca dla zakresu DATA i zakresu INDEX. Nazwa DUAL wydawała się trafna w procesie tworzenia pary rzędów z jednego.

Oryginalna tabela DUAL zawierała dwa wiersze (stąd nazwa), ale później miała tylko jeden wiersz.

Kawałki bekonu
źródło
3
+1 i witamy na dba.se. To doskonała odpowiedź z fascynującą historią - mam nadzieję, że możesz zostać zachęcony do pozostania i przyczynienia się więcej :)
Jack mówi, spróbuj wypróbować topanswers.xyz 12.12. O
4
Miałem godziny niekończącej się zabawy, gdy programista wstawił jeszcze kilka wierszy do podwójnego. Zepsułem wiele rzeczy :) Trochę czasu zajęło wytropienie winowajcy!
Philᵀᴹ
8

Zaletą dualjest to, że optymalizator rozumie, że dualjest to specjalna tabela z jednym wierszem i jedną kolumną (z varchar2typem danych) - gdy używasz go w zapytaniach, wykorzystuje tę wiedzę przy opracowywaniu planu.

Dlaczego musimy wybierać dualw Oracle?

Możesz także wybierać spośród dualwłasnych stolików lub ze swoich stołów, możesz, jeśli chcesz.

Dla mnie pozostanę, dualbo wiem dual, że istnieje. Wiem, że ma co najmniej 1, a maksymalnie 1 wiersz. Wiem, że optymalizator wie wszystko duali robi dla mnie najbardziej wydajną rzecz. Optymalizator rozumie, że dualto magiczny, specjalny 1-rzędowy stół. Zatrzymał się, select *ponieważ musi tam być jeden rząd. Tak to działa.

DevYudh
źródło
„Wiem, że ma co najmniej 1, a maksymalnie 1 wiersz”. Cóż, kretyn (lub idiota) z uprawnieniami DBA może modyfikowaćDUAL . Bądź ostrożny!
Nick Chammas
cóż, jeśli ci się to przytrafi. cofnąć wszystkie uprawnienia z wyjątkiem UTWÓRZ SESJĘ od tej Ktoś. a co, jeśli ktoś przypadkowo upuścił dual?
DevYudh
możesz go utworzyć za pomocą opcji tworzenia tabeli podwójnej (dummy varchar2 (1)) Storage (początkowy 1) lub tabeli flashback dual do przed upuszczeniem
DevYudh
Cóż, zaletą jest użycie DUAL w porównaniu z wybraniem wyrażenia z dowolnej istniejącej tabeli, ale nie wyjaśnia, jaka jest korzyść z posiadania DUAL jako alternatywy dla braku konieczności posiadania FROM, jak w PostgreSQL lub SQLServer
Danubian Sailor
@ Łukasz Lech w Oracle nie ma WYBORU bez FROM dla # MSSQL Serv: W SQL Server nie ma potrzeby używania podwójnej tabeli. ale jeśli przeniosłeś swój kod z Oracle na SQL Serv, możesz utworzyć dual za pomocą tego skryptu UTWÓRZ PODWÓJNY TABELĘ (DUMMY VARCHAR (1)) PRZEJDŹ DO WARTOŚCI PODWÓJNYCH (DUMMY) („X”) GO, ale nie widzę żadnych powód, aby użyć / utworzyć podwójną tabelę na serwerze SQL. a także MSSQL Serv i PostGRE SQL nie wymagają tabeli Dummy
DevYudh 19.09.2013
1

Pozostałe dwie odpowiedzi stanowią dobre tło dla mojej odpowiedzi.

W bazach danych Oracle jest tradycyjny i niezawodny. Nie powiedzie się w innych bazach danych, które nie mają DUALtabeli. Nie jest konieczne, abyś używał DUAL, ale polecam to zrobić.

Bazy danych zgodne ze standardami będą wymagały FROMklauzuli określającej co najmniej odwołanie do tabeli. Jeśli masz tabelę ZAMÓWIENIA FROM DUAL, działałaby następująca zamiana klauzuli:

FROM   orders
WHERE  rownum =1

Zastąp dowolną tabelę lub widok, który możesz wybrać, i będzie działać. Zastąp tabelę lub widok, którego nie możesz wybrać, a to się nie powiedzie. DUALjest bardziej niezawodny, ponieważ wykluczając złamanie DBA, wszyscy użytkownicy mogą z niego wybierać i otrzyma tylko jeden wiersz w zestawie wyników. (Czasami się psuje.)

Nie znam standardowego czasownika dostępu do danych, których nie ma w tabeli bez odwołania do tabeli. Biorąc pod uwagę, jak mało dostępu do takich danych, nie widzę takiej potrzeby. Wiele przypadków, na które natrafiam, można lepiej traktować na różne sposoby.

BillThor
źródło
2
SELECT CURRENT_TIMESTAMP FROM (VALUES(1)) V(C)wierzę, że jest zgodny ze standardami i nie polega na żadnym konkretnym stole.
Martin Smith,
@MartinSmith Zaktualizowałem moją odpowiedź, aby użyć odwołania do tabeli. Właśnie to miałem na myśli i powinienem był określić.
BillThor,