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


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.