MySQL เทียบเท่ากับ WITH in oracle


คำตอบ:


16

นั่นไม่ใช่. เว้นแต่ (จนกว่า) จะมีการพัฒนา (MySQL เป็นโอเพนซอร์สทุกคนสามารถมีส่วนร่วมได้)

WITHคีย์เวิร์ดANSI / ISO SQL ใช้เพื่อกำหนด Common Table Expressions (CTEs) และช่วยลดความซับซ้อนของเคียวรีที่ซับซ้อนด้วยการอ้างอิงแบบซ้อนหนึ่งหรือหลายแบบ มันมีอยู่ใน Oracle, Postgres, SQL-Server, DB2 แต่ไม่ใช่ใน MySQL

แบบสอบถามสุดท้ายอาจมีการอ้างอิง (โดยปกติจะอยู่ในFROMข้อ แต่อาจอยู่ในส่วนอื่น ๆ ) ให้กับทุกคนที่มีการแสดงออกของตารางทั่วไปอย่างน้อยหนึ่งครั้ง สามารถเขียนแบบสอบถาม (ไม่มี CTEs) ใน MySQL โดยใช้ตารางที่ได้รับ แต่การอ้างอิงจะต้องทำซ้ำ ๆ

ตัวอย่างของข้อความค้นหาโง่ ๆ ที่แสดงให้เห็นว่าทุกคนเกิดใน 50 ปีและในเดือนกรกฎาคมและจำนวนคนทั้งหมดที่เกิดในปีเดียวกัน:

WITH a AS
    ( SELECT name, birthdate, YEAR(birthdate) AS birthyear
      FROM persons
      WHERE birthdate >= '1950-01-01' AND birthdate < '1960-01-01' 
    ) 
, b AS
    ( SELECT birthyear, COUNT(*) AS cnt
      FROM a
      GROUP BY birthyear 
    ) 
SELECT a.name, a.birthdate, b.cnt AS number_of_births
FROM a JOIN b
  ON a.birthyear = b.birthyear 
WHERE MONTH(a.birthdate) = 7 ;

ใน MySQL มันสามารถเขียนเป็น:

SELECT a.name, a.birthdate, b.cnt AS number_of_births
FROM 
    ( SELECT name, birthdate, YEAR(birthdate) AS birthyear
      FROM persons
      WHERE birthdate >= '1950-01-01' AND birthdate < '1960-01-01' 
    ) AS a 
  JOIN 
    ( SELECT birthyear, COUNT(*) AS cnt
      FROM 
        ( SELECT name, birthdate, YEAR(birthdate) AS birthyear
          FROM persons
          WHERE birthdate >= '1950-01-01' AND birthdate < '1960-01-01' 
        ) AS aa
      GROUP BY birthyear
    ) AS b
  ON a.birthyear = b.birthyear 
WHERE MONTH(a.birthdate) = 7 ;

aขอให้สังเกตการทำสำเนาของรหัสสำหรับตารางที่ได้รับ ในแบบสอบถามที่ซับซ้อนมากขึ้นรหัสจะต้องถูกเขียนหลายครั้ง


เพื่อหลีกเลี่ยงการทำซ้ำ (ซ้ำซ้อนของรหัส) จะดีกว่าไหมถ้าใช้ตัวแปรและตารางชั่วคราว?
Pacerier

ฉันจะไม่กังวลเกี่ยวกับการทำซ้ำของรหัส แต่แน่นอนฉันจะพิจารณาและลองเวอร์ชันที่มีตารางชั่วคราวเพื่อเหตุผลด้านประสิทธิภาพ
ypercubeᵀᴹ

1
ทำไมคุณถึงบอกว่าคุณไม่ต้องกังวลกับการทำซ้ำของรหัส? นี่คือยุ่งทันทีและยกเลิก  แห้ง
Pacerier

1
@Pacerier DRY ไม่เกี่ยวข้องกับรหัส DB เสมอไป
JNK

1
@Pierier ฉันจะไม่แปลกใจถ้ามันไม่ใช่ เอ็นจิ้นฐานข้อมูลจำเป็นต้องคาดเดาเกี่ยวกับสิ่งที่จะทำงานได้ดีที่สุดในขณะที่ยังรับประกันว่าจะให้ผลลัพธ์ที่ถูกต้อง ตารางชั่วคราวโดยทั่วไปนั้นใช้ได้ แต่ DRY นำไปสู่ประสิทธิภาพที่แย่มากในฐานข้อมูลในด้านอื่น ๆ เช่นฟังก์ชันที่ผู้ใช้กำหนด
JNK

2

ที่จะทำงาน แต่ก็น่าเสียดายที่มันจะไม่ให้ประโยชน์จากการใช้คำสั่ง WITH ที่ไม่ได้ดำเนินการแบบสอบถามเดียวกันหลายครั้ง (ด้วยแบบสอบถามที่ซับซ้อนอาจ reaaaally ช้าและเรียกร้องมากสำหรับเครื่องมือฐานข้อมูลนั้นฉันประสบมัน) .

ฉันขอแนะนำให้ใส่แต่ละ SELECT เดิมที่กำหนดไว้ในข้อลงในตารางชั่วคราวของตัวเองและใช้พวกเขาภายในแบบสอบถาม ใน MySQL ตารางชั่วคราวจะลดลงเมื่อเซสชันผู้ใช้สิ้นสุด

แก้ไข:

ฉันเพิ่งเห็นคำตอบนี้ในชุดข้อความที่คล้ายกันซึ่งแสดงวิธีแก้ปัญหาทั้ง 3 อย่างด้วย MySQL :

  • ตารางชั่วคราว
  • DERIVED ตาราง
  • มุมมองอินไลน์ (อย่างมีประสิทธิภาพสิ่งที่มีส่วนคำสั่งกับ - พวกเขาจะใช้แทนกันได้)

/programming//a/1382618/2906290

และตัวอย่างของโพรซีเดอร์ MySQL ที่สร้างและวางตารางชั่วคราวในกรณีที่คุณดำเนินการต่อกับเซสชันของคุณและต้องการเพิ่มทรัพยากรเหล่านั้น (ฉันจะใช้มันเป็นตัวอย่างของไวยากรณ์): /programming//a/ 5553145/2906290

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