MySQL“ ด้วย” ประโยค


98

ฉันกำลังพยายามใช้ MySQL เพื่อสร้างมุมมองที่มีอนุประโยค "ด้วย"

WITH authorRating(aname, rating) AS
   SELECT aname, AVG(quantity)
   FROM book
   GROUP BY aname

แต่ดูเหมือนว่า MySQL จะไม่รองรับสิ่งนี้

ฉันคิดว่านี่เป็นมาตรฐานที่ดีและฉันแน่ใจว่า Oracle รองรับสิ่งนี้ มีการบังคับให้ MySQL ใช้อนุประโยค "ด้วย" หรือไม่? ฉันได้ลองใช้กับโปรแกรม MyISAM และ innoDB แล้ว ทั้งสองอย่างนี้ไม่ได้ผล

คำตอบ:


109

อัปเดต: ในที่สุด MySQL 8.0 ก็ได้รับคุณลักษณะของนิพจน์ตารางทั่วไปรวมถึง CTE แบบเรียกซ้ำ

นี่คือบล็อกที่ประกาศ: http://mysqlserverteam.com/mysql-8-0-labs-recursive-common-table-expressions-in-mysql-ctes/

ด้านล่างนี้คือคำตอบก่อนหน้าของฉันซึ่งฉันเขียนไว้ในปี 2008


MySQL 5.x ไม่รองรับการสืบค้นโดยใช้WITHไวยากรณ์ที่กำหนดใน SQL-99 หรือที่เรียกว่าCommon Table Expressions

นี่เป็นคำขอคุณลักษณะสำหรับ MySQL ตั้งแต่เดือนมกราคม 2549: http://bugs.mysql.com/bug.php?id=16244

ผลิตภัณฑ์ RDBMS อื่น ๆ ที่รองรับนิพจน์ตารางทั่วไป:


1
SQLite รองรับส่วนคำสั่ง WITHในเวอร์ชัน 3.8.3 ที่เผยแพร่เมื่อ 2014-02-03
Martijn

ฉันเพิ่ม H2 และ Firebird ลงในรายการ
a_horse_with_no_name

2
@BillKarwin: ฉันไม่เชื่อว่า MySQL จะใช้คุณลักษณะ DBMS ที่ทันสมัยใด ๆ (ตรวจสอบข้อ จำกัด ฟังก์ชันหน้าต่างดัชนีของนิพจน์ดัชนีบางส่วนข้อ จำกัด ที่รอการตัดบัญชี ... )
a_horse_with_no_name

2
@a_horse_with_no_name ดูเหมือนว่าพวกเขาจะให้ความสำคัญกับความสามารถในการปรับขนาดสูงกว่ามาก พวกเขาให้ความสำคัญกับการทำให้ภายในปรับขนาดได้มากขึ้นเพื่อใช้ประโยชน์จากฮาร์ดแวร์ที่ทันสมัยมาเป็นเวลานาน แต่ฉันคิดว่าพวกเขาละเลยคุณสมบัติของ SQL
Bill Karwin

1
@BlakeMcBride คุณคิดผิดความคิดเห็นของคุณคือ FUD และไม่มีพื้นฐานในความเป็นจริง Oracle ยังเป็นเจ้าของผลิตภัณฑ์ฐานข้อมูลอื่น ๆ ที่ทำสิ่งที่ Oracle DB ทำได้ไม่ดี ตัวอย่าง: TimesTen, BerkeleyDB พวกเขาได้รับฐานข้อมูลเหล่านั้นเพื่อขยายตลาด MySQL มีความโดดเด่นในตลาดเว็บแอปพลิเคชันและ Oracle DB ไม่ใช่ดังนั้นพวกเขาจึงซื้อ MySQL ไม่มีเหตุผลที่ Oracle จะเอ็นร้อยหวาย MySQL ฉันได้พูดคุยกับนักพัฒนา Oracle MySQL ในการประชุมเมื่อเดือนเมษายนและในความเป็นจริงพวกเขากำลังดำเนินการเกี่ยวกับการใช้งานกับ MySQL
Bill Karwin

17

คุณอาจสนใจในบางสิ่งเช่นนี้:

select * from (
    select * from table
) as Subquery

คุณช่วยอธิบาย Subquery ได้ไหม ฉันขอเลือก * จาก ((เลือก * จากตาราง 1) UNION ALL (เลือก * จาก table2)) จัดกลุ่มตามบางสิ่งได้ไหม

1
@Kathy สวัสดีSubqueryเป็นชื่อที่ฉันใช้สำหรับตารางที่ได้มานั้นเอง เมื่อคุณใช้from ( ... )คุณสร้างบางสิ่งบางอย่างเช่นตารางชั่วคราว (ตารางที่ได้รับ) และต้องใช้ชื่อ as Subqueryนั่นเป็นเหตุผลที่ผมใช้ ตอบคำถามของคุณใช่คุณทำได้ แต่คุณจะต้องใส่ชื่อในตารางที่ได้รับด้านนอก (ก่อนหน้าGroup By) หวังว่าจะช่วยได้
Mosty Mostacho

@MostyMostacho สวัสดีค่ะช่วยตักอาหารให้ฉันหน่อยได้ไหม ฉันกำลังดิ้นรนเพื่อแปลงเป็น MySQL ลองดูหน่อยได้ไหม ลิงค์หรือตอบคำถามของฉันที่นี่อาจจะ? ลิงค์
Pranav

13

คุณมีไวยากรณ์ที่ถูกต้อง:

WITH AuthorRating(AuthorName, AuthorRating) AS
   SELECT aname         AS AuthorName,
          AVG(quantity) AS AuthorRating
   FROM Book
   GROUP By Book.aname

อย่างไรก็ตามตามที่คนอื่นกล่าวมา MySQL ไม่รองรับคำสั่งนี้ C ถูกเพิ่มใน SQL: 1999; เวอร์ชันล่าสุดของมาตรฐาน SQL คือ SQL: 2008 คุณสามารถค้นหาข้อมูลเพิ่มเติมเกี่ยวกับฐานข้อมูลที่สนับสนุน SQL: คุณสมบัติต่างๆปี 1999 ในวิกิพีเดีย

MySQL มีความล่าช้าเล็กน้อยในการรองรับมาตรฐาน SQL ในขณะที่ฐานข้อมูลเชิงพาณิชย์เช่น Oracle, SQL Server (เมื่อเร็ว ๆ นี้) และ DB2 ได้ติดตามพวกเขาอย่างใกล้ชิดมากขึ้น PostgreSQL มักจะเป็นไปตามมาตรฐานที่สวยงามเช่นกัน

คุณอาจต้องการดูแผนงานของ MySQL ฉันไม่แน่ใจว่าเมื่อใดที่ฟีเจอร์นี้อาจได้รับการสนับสนุน แต่ก็ยอดเยี่ยมสำหรับการสร้างการค้นหาแบบสรุปที่อ่านได้


11

Oracle รองรับด้วย

มันจะเป็นแบบนี้

WITH emps as (SELECT * FROM Employees)
SELECT * FROM emps WHERE ID < 20
UNION ALL
SELECT * FROM emps where Sex = 'F'

@ysth C ยากสำหรับ Google เนื่องจากเป็นคำทั่วไปที่มักไม่รวมอยู่ในการค้นหา

คุณต้องการดูไฟล์ เอกสาร SELECTเพื่อดูว่าการแยกตัวประกอบของแบบสอบถามย่อยทำงานอย่างไร

ฉันรู้ว่าสิ่งนี้ไม่ตอบโจทย์ OP แต่ฉันกำลังทำความสับสนที่อาจเกิดขึ้น


ยังไม่คลายความสับสนของฉันอยู่ดี คุณกำลังบอกว่าไม่มีประโยค WITH แต่มีคำสั่ง WITH ใช่หรือไม่?
ysth

1
ฉันเห็น เป็นอนุประโยคของการเลือกที่นำหน้าการเลือก สามารถใช้ใน CREATE VIEW ด้วยได้หรือไม่? แตกต่างจากการเข้าร่วมการเลือกย่อยอย่างไร? ฉันไม่เห็นตัวอย่างออนไลน์ที่ชื่อหลัง C มีพารามิเตอร์ - มันทำงานอย่างไร
ysth

1
มันแตกต่างกันมาก สังเกตว่ามีการใช้ subqry เดียวกันสองครั้งโดยไม่ต้องกำหนดซ้ำสองครั้ง แน่ใจว่าคุณสามารถคัดลอก / วางข้อความค้นหาเดียวกันในนั้นได้ แต่นี่เป็นตัวอย่างง่ายๆ ลองนึกภาพว่าประโยคที่มีอยู่บนหน้าและถูกใช้ 4 ครั้งในการสืบค้นหลัก แล้วคุณจะประทับใจ

ฉันเชื่อมโยงกับเอกสารที่ควรอธิบายไวยากรณ์ เท่าที่ดู แน่นอนว่าทำงานที่นั่น

3

จากคำตอบจาก @Mosty Mostacho นี่คือวิธีที่คุณอาจทำสิ่งที่เทียบเท่าใน MySQL สำหรับกรณีเฉพาะในการพิจารณาว่ารายการใดไม่มีอยู่ในตารางและไม่อยู่ในฐานข้อมูลอื่น

select col1 from (
   select 'value1' as col1 union
   select 'value2' as col1 union
   select 'value3' as col1
) as subquery
left join mytable as mytable.mycol = col1
where mytable.mycol is null
order by col1

คุณอาจต้องการใช้โปรแกรมแก้ไขข้อความที่มีความสามารถของมาโครเพื่อแปลงรายการค่าเป็นอนุประโยคเลือกที่ยกมา




0

คุณเคยลอง Temporary Table หรือไม่? สิ่งนี้แก้ไขการบรรจบกันของฉัน:

create temporary table abc (
column1 varchar(255)
column2 decimal
);
insert into abc
select ...
or otherwise
insert into abc
values ('text', 5.5), ('text2', 0815.8);

จากนั้นคุณสามารถใช้ตารางนี้ในทุกการเลือกในเซสชันนี้:

select * from abc inner join users on ...;

1
ฉันต้องทราบ: stackoverflow.com/questions/343402/…คุณไม่สามารถเปิดตารางได้สองครั้ง :-(
Claus

My Sollution สำหรับชุดข้อมูลขนาดเล็กในตาราง: สร้างตาราง abc2 เช่น abc; แทรกลงใน abc2 เลือก * จาก abc;
Claus
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.