ทำไมฉันต้องเลือกจากตารางคู่


15

ผลงานในฐานข้อมูลความสัมพันธ์ที่สำคัญระบบการจัดการนี้ส่วนใหญ่มีแนวโน้มที่จะปรากฏใน StackOverflow / dba.stackexchange เป็นSQL Server, MySQL, PostgreSQL และ SQLite (WebSQL)

select 'abc' abc, 1 def;

มันไม่ทำงานบน Oracle ทำไมเราต้องเลือกจาก DUAL ใน 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 fromDB2 มีตารางหุ่นคล้ายกันเรียกว่าSYSIBM.SYSDUMMY1 นอกจากนี้คุณอาจจะรู้อยู่แล้วว่านี้ แต่เมื่อคุณselect 'A' from dualที่dualโต๊ะไม่สามารถเข้าถึงจริงๆซึ่งเป็นคำตอบคำถามในการแก้ไขของคุณ (ซึ่งสมควรได้รับคำถามใหม่ครับ)
แจ็คบอกว่าลอง topanswers.xyz

1
มันไม่ทำงานใน DBMS "ทั้งหมด" มีหลาย 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

1
DB2 ไม่จำเป็นต้องมีข้อจาก 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 สร้างโดย Charles Weiss ของ บริษัท Oracle เพื่อจัดทำตารางสำหรับการเข้าร่วมในมุมมองภายใน:

ฉันสร้างตาราง DUAL เป็นวัตถุพื้นฐานใน Oracle Data Dictionary มันไม่ได้ตั้งใจจะมองเห็นตัวเอง แต่ใช้ในมุมมองที่คาดว่าจะถูกถามแทน แนวคิดคือคุณสามารถเข้าร่วมกับตาราง DUAL และสร้างสองแถวในผลลัพธ์สำหรับทุก ๆ แถวในตารางของคุณ จากนั้นโดยใช้ GROUP BY การสรุปผลการเข้าร่วมสามารถแสดงจำนวนหน่วยเก็บข้อมูลสำหรับขอบเขตข้อมูลและขอบเขตดัชนี ชื่อ DUAL ดูเหมือนจะเหมาะสำหรับกระบวนการสร้างแถวหนึ่งแถวจากแถวเดียว

ตาราง DUAL ดั้งเดิมมีสองแถวในนั้น (ด้วยเหตุนี้ชื่อ) แต่ต่อมามันมีเพียงหนึ่งแถว


3
+1 และยินดีต้อนรับสู่ dba.se นี่เป็นคำตอบที่ยอดเยี่ยมพร้อมประวัติอันน่าทึ่ง - ฉันหวังว่าคุณจะได้รับการสนับสนุนให้ติดและมีส่วนร่วมมากขึ้น :)
แจ็คบอกว่าลอง topanswers.xyz

4
ฉันได้สนุกไม่รู้จบมาหลายครั้งครั้งหนึ่งเมื่อผู้พัฒนาแทรกแถวอีกสองสามแถวเป็นคู่ ทำลายสิ่งต่าง ๆ มากมาย :) ใช้เวลาสักพักเพื่อติดตามผู้กระทำผิด!
Philᵀᴹ

8

ข้อได้เปรียบที่จะdualเป็นเครื่องมือเพิ่มประสิทธิภาพเข้าใจdualเป็นพิเศษหนึ่งแถวหนึ่งตารางคอลัมน์ (พร้อมvarchar2ชนิดข้อมูล) - เมื่อคุณใช้ในแบบสอบถามมันจะใช้ความรู้นี้เมื่อพัฒนาแผน

ทำไมเราต้องเลือกจากdualใน Oracle

คุณสามารถเลือกจากdualหรือจากตารางของคุณเองได้เช่นกันหากคุณต้องการ

สำหรับฉันฉันจะติดdualเพราะฉันรู้ว่าdualมีอยู่ ฉันรู้ว่ามันมีอย่างน้อย 1 และสูงสุด 1 แถว ฉันรู้ว่าเครื่องมือเพิ่มประสิทธิภาพรู้ทุกอย่างdualและทำสิ่งที่มีประสิทธิภาพที่สุดสำหรับฉัน เครื่องมือเพิ่มประสิทธิภาพเข้าใจว่าdualเป็นตารางมายากล 1 แถวพิเศษ มันหยุดที่select *เพราะจะต้องมีหนึ่งแถวในนั้น ดังนั้นมันจึงเป็นวิธีการทำงาน


"ฉันรู้ว่ามันมีอย่างน้อย 1 และไม่เกิน 1 แถว" ดีกระตุก (หรืองี่เง่า) มีสิทธิ์ DBA สามารถปรับเปลี่ยน DUALระวัง!
Nick Chammas

ดีถ้าเกิดขึ้นกับคุณ เพิกถอนสิทธิ์ทั้งหมดยกเว้น CREATE SESSION จากบุคคลนี้ และจะเกิดอะไรขึ้นถ้ามีคนตกหล่นคู่โดยบังเอิญ
DevYudh

คุณสามารถสร้างมันได้โดยใช้ create table dual (dummy varchar2 (1)) ที่เก็บข้อมูล (เริ่มต้น 1) หรือตารางย้อนหลังเป็นคู่ก่อนถึงดรอป
DevYudh

มันเป็นข้อได้เปรียบในการใช้ DUAL เมื่อเทียบกับการเลือกนิพจน์จากตารางอื่นที่มีอยู่ แต่ไม่ได้อธิบายว่าอะไรคือข้อดีของการมี DUAL เป็นทางเลือกสำหรับการไม่ต้องมี FROM เช่นใน PostgreSQL หรือ SQLServer
Danubian Sailor

@Lukasz Lech ใน Oracle ไม่มี SELECT โดยไม่ต้องใช้สำหรับ #MSSQL Serv: ไม่จำเป็นต้องใช้ Dual table ใน SQL Server เลย แต่ถ้าคุณโอนรหัสจาก oracle ไปยัง SQL Serv คุณสามารถสร้าง dual โดยใช้สคริปต์นี้สร้างตารางคู่ (DUMMY VARCHAR (1)) GO INSERT INTO DUAL (DUMMY) VALUES ('X') GO แต่ฉันไม่เห็นเลย เหตุผลที่ใช้ / สร้างตารางคู่ในเซิร์ฟเวอร์ sql และ MSSQL Serv และ PostGRE SQL ไม่ต้องการตาราง Dummy
DevYudh

1

อีกสองคำตอบให้พื้นหลังที่ดีสำหรับคำตอบของฉัน

บนฐานข้อมูล Oracle เป็นฐานข้อมูลดั้งเดิมและเชื่อถือได้ มันจะล้มเหลวในฐานข้อมูลอื่น ๆ ที่ไม่มีDUALตาราง ไม่จำเป็นว่าคุณจะต้องใช้DUALแต่ฉันอยากจะแนะนำให้คุณทำ

ฐานข้อมูลที่เป็นไปตามมาตรฐานจะต้องมีFROMประโยคที่ระบุอย่างน้อยการอ้างอิงตาราง หากคุณมีตารางคำสั่งซื้อการแทนที่คำสั่งต่อไปนี้FROM DUALจะใช้งานได้:

FROM   orders
WHERE  rownum =1

แทนที่ตารางหรือมุมมองใด ๆ ที่คุณสามารถเลือกได้และมันจะทำงาน แทนที่ตารางหรือมุมมองที่คุณไม่สามารถเลือกได้และมันจะล้มเหลว DUALมีความน่าเชื่อถือมากกว่าการ จำกัด DBA ให้ทำลายผู้ใช้ทุกคนสามารถเลือกได้และจะได้รับเพียงหนึ่งแถวในชุดผลลัพธ์ (มันจะแตกเป็นครั้งคราว)

ฉันไม่รู้จักกริยาที่เป็นไปตามมาตรฐานสำหรับการเข้าถึงข้อมูลที่ไม่ได้อยู่ในตารางโดยไม่รวมการอ้างอิงตาราง เมื่อฉันเข้าถึงข้อมูลดังกล่าวฉันจะไม่เห็นความต้องการดังกล่าว หลายกรณีที่ฉันพบสามารถจัดการได้ดีขึ้นในวิธีที่ต่างกัน


2
SELECT CURRENT_TIMESTAMP FROM (VALUES(1)) V(C)เป็นไปตามมาตรฐานที่ฉันเชื่อและไม่พึ่งพาตารางใด ๆ
Martin Smith

@MartinSmith ฉันได้อัปเดตการตอบสนองของฉันเพื่อใช้การอ้างอิงตาราง นี่คือสิ่งที่ฉันหมายถึงและควรมีการระบุ
BillThor
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.