Чому мені потрібно вибрати з подвійної таблиці?


15

Це працює в основних системах управління базами даних відносин, які, швидше за все, з'являються на StackOverflow / dba.stackexchange, будучи SQL Server, MySQL, PostgreSQL і SQLite (WebSQL) .

select 'abc' abc, 1 def;

Це не працює на Oracle. Чому нам потрібно вибрати OUAL в Oracle? Чи вимагає стандарт ISO / ANSI для SQL пункт FROM для операторів SELECT ?


Редагувати:

Відповідь Bacon Bitвідповіді, здається, вимагає стандарт SQL.

Тож насправді тому, що назва DUAL - це така помилка, якби я створив таблицю та назвав її ATOM чи ONE, наприклад 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таблиця на насправді не доступний , який відповідає на питання правки (який заслуговує нове питання до речі).
Джек каже, спробуйте topanswers.xyz

1
Він не працює у "всіх" СУБД. Існує декілька СУБД, які не дозволяють SELECT без ВІД. Посібник відповідає на ваше запитання щодо продуктивності: 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

1
DB2 вимагає пропозиції FROM, але альтернативою є використання оператора типу values ('abc', 1). Звичайно, ви також можете вибрати з такого твердження:select abc from ( values ('abc',1) ) as t(abc,def)
Леннарт

Відповіді:


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()(або будь-який інший ваш діалект воліє), ми на самому ділі не хочуть дані з таблиці.

Oracle вирішує вирішити невідповідність стандарту та впровадженню за допомогою макетної таблиці із наступним ефективним визначенням:

CREATE TABLE DUAL (
  DUMMY CHAR(1)
  )

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

Інші RDBMS по суті припускають, що використовується фіктивна таблиця, якщо не FROMвказано ні.

Історія DUAL таблиці на Вікіпедії:

Таблиця DUAL була створена корпорацією Чарльз Вайс з корпорації Oracle для надання таблиці для приєднання до внутрішніх поглядів:

Я створив таблицю DUAL як основний об'єкт у словнику даних Oracle. Він ніколи не мав на увазі бачити себе, а замість цього використовувався всередині подання, яке, як очікувалося, буде запитуватися. Ідея полягала в тому, що ви можете зробити приєднання до таблиці DUAL і створити результат у двох рядках для кожного рядка таблиці. Тоді, використовуючи GROUP BY, отримане з'єднання можна підсумувати, щоб показати об'єм сховища для обсягу DATA та для обсягу (-ів) INDEX. Назва, DUAL, здавалася придатною для процесу створення пари рядків із лише одного.

Оригінальна таблиця DUAL мала в ній два ряди (звідси її назва), але згодом вона мала лише один рядок.


3
+1 і ласкаво просимо на dba.se. Це відмінна відповідь із захоплюючою частиною історії - я сподіваюся, що вас можуть заохотити дотримуватися та робити більше
прикладів

4
Години нескінченної забави були у мене одного разу, коли розробник вставив ще кілька рядків у подвійний. Зламав багато речей :) Знадобився час, щоб вистежити винуватця!
Philᵀᴹ

8

Перевага dual, яку оптимізатор розуміє, dual- це спеціальна одна рядок, одна таблиця стовпців (з varchar2типом даних) - коли ви використовуєте її в запитах, він використовує ці знання при розробці плану.

Чому нам потрібно вибрати dualв Oracle?

Ви також можете вибрати з dualвласних таблиць або з них, якщо хочете.

Для мене я буду дотримуватися, dualтому що я знаю, що dualіснує. Я знаю, що він має принаймні 1 і максимум 1 ряд. Я знаю, що оптимізатор знає все dualі робить для мене найефективнішу річ. Оптимізатор розуміє dual- це чарівний, спеціальний 1 рядовий стіл. Він зупинився на select *тому, що там має бути один ряд. Так що це просто так.


"Я знаю, що в ньому є щонайменше 1 і максимум 1 ряд." Ну, ривок (або ідіот) з привілеями DBA може змінитиDUAL . Будь обережний!
Нік Чаммас

добре, якщо це трапиться з вами. скасовують усі привілеї, за винятком ТВОРЧОЇ СЕСІЇ, від цієї Когось Особи. а що робити, якщо подвійний хтось випадково кинув?
DevYudh

ви можете створити його за допомогою створення таблиці подвійного (манекена varchar2 (1)) зберігання (початковий 1) або таблиці
зворотного звороту

Ну, це перевага у використанні DUAL порівняно з вибором виразу з будь-якої іншої існуючої таблиці, але це не пояснює, яка перевага мати DUAL як альтернативу тому, що не мати FROM, як у PostgreSQL або SQLServer
Danubian Sailor

@Lukasz Lech в Oracle не існує SELECT без FROM для #MSSQL Serv: В SQL Server взагалі не потрібно подвійної таблиці. але якщо ви передали свій код з Oracle на SQL Serv, ви можете створити подвійний за допомогою цього скрипту. СТВОРИТИ ТАБЛИЧНУ ТАБЛИЦЮ (DUMMY VARCHAR (1)) ВСТУПУЙТЕ В ДУАЛЬНІ (DUMMY) ЦІННОСТІ ('X') GO, але я не бачу жодної причина використовувати / створити подвійну таблицю на сервері sql. а також MSSQL Serv та PostGRE SQL не потребують таблиці "
Дамі"

1

Два інших відповіді слугують гарним підґрунтям для моєї відповіді.

На базі даних Oracle це традиційно та надійно. Він не працює в інших базах даних, у яких немає DUALтаблиці. Це не обов'язково, що ви використовуєте DUAL, але я б рекомендував вам це зробити.

Бази даних, сумісні зі стандартами, потребують FROMпункту із зазначенням принаймні посилання на таблицю. Якщо у вас є таблиця ЗАМОВЛЕННЯ, наступна заміна цього FROM DUALпункту спрацює:

FROM   orders
WHERE  rownum =1

Замініть будь-яку таблицю або перегляд, який ви можете обрати, і це спрацює. Замініть таблицю або представлення, яке ви не можете вибрати, і воно не вдасться. DUALє більш надійним, оскільки заборона DBA розбиває її, всі користувачі можуть вибрати з неї і отримає лише один рядок у наборі результатів. (Іноді вона ламається.)

Мені не відомо про дієслово, сумісне зі стандартами, для доступу до даних, які не є в таблиці, не включаючи посилання на таблицю. Зважаючи на те, як мало я отримую доступ до таких даних, я не бачу такої потреби. Багато випадків, з якими я стикаюся, можна краще вирішувати різними способами.


2
SELECT CURRENT_TIMESTAMP FROM (VALUES(1)) V(C)Я відповідаю стандартам, я вважаю, і не покладається на будь-який конкретний стіл.
Мартін Сміт

@MartinSmith Я оновив свою відповідь, щоб використовувати посилання на таблицю. Це те, що я мав на увазі і повинен був уточнити.
BillThor
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.