ในแบบสอบถาม MySQL ทำไมต้องใช้ join แทน Where?


109

ดูเหมือนว่าจะรวมสองตารางขึ้นไปเราสามารถใช้การเข้าร่วมหรือที่ไหนก็ได้ ข้อดีของข้อหนึ่งคืออะไร?


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

สิ่งนี้ตอบคำถามของคุณหรือไม่? INNER JOIN ON vs WHERE clause
philipxy

คำตอบ:


161

การสืบค้นใด ๆ ที่เกี่ยวข้องกับตารางมากกว่าหนึ่งตารางจำเป็นต้องมีการเชื่อมโยงบางรูปแบบเพื่อเชื่อมโยงผลลัพธ์จากตาราง "A" ไปยังตาราง "B" วิธีการดั้งเดิม (ANSI-89) ในการทำสิ่งนี้คือ:

  1. แสดงรายการตารางที่เกี่ยวข้องในรายการที่คั่นด้วยจุลภาคในส่วนคำสั่ง FROM
  2. เขียนความสัมพันธ์ระหว่างตารางในส่วนคำสั่ง WHERE

    SELECT *
      FROM TABLE_A a,
           TABLE_B b
     WHERE a.id = b.id

นี่คือข้อความค้นหาที่เขียนขึ้นใหม่โดยใช้ไวยากรณ์ ANSI-92 JOIN:

SELECT *
  FROM TABLE_A a
  JOIN TABLE_B b ON b.id = a.id

จากมุมมองด้านประสิทธิภาพ:


ในกรณีที่รองรับ (Oracle 9i +, PostgreSQL 7.2+, MySQL 3.23+, SQL Server 2000+) ไม่มีประโยชน์ด้านประสิทธิภาพในการใช้ไวยากรณ์อย่างใดอย่างหนึ่งกับอีกแบบ เครื่องมือเพิ่มประสิทธิภาพจะมองว่าเป็นข้อความค้นหาเดียวกัน แต่การสืบค้นที่ซับซ้อนมากขึ้นจะได้รับประโยชน์จากการใช้ไวยากรณ์ ANSI-92:

  • ความสามารถในการควบคุมคำสั่ง JOIN - ลำดับที่จะสแกนตาราง
  • ความสามารถในการใช้เกณฑ์การกรองบนโต๊ะก่อนเข้าร่วม

จากมุมมองการบำรุงรักษา:


มีเหตุผลมากมายในการใช้ไวยากรณ์ ANSI-92 JOIN บน ANSI-89:

  • อ่านได้มากขึ้นเนื่องจากเกณฑ์การเข้าร่วมนั้นแยกจากส่วนคำสั่ง WHERE
  • มีโอกาสน้อยที่จะพลาดเกณฑ์การเข้าร่วม
  • การสนับสนุนไวยากรณ์ที่สอดคล้องกันสำหรับประเภท JOIN อื่นที่ไม่ใช่ INNER ทำให้แบบสอบถามใช้งานง่ายบนฐานข้อมูลอื่น
  • WHERE clause ทำหน้าที่กรองผลิตภัณฑ์คาร์ทีเซียนของตารางที่เข้าร่วมเท่านั้น

จากมุมมองการออกแบบ:


ไวยากรณ์ ANSI-92 JOIN เป็นรูปแบบไม่ใช่ต่อต้านรูปแบบ:

  • จุดประสงค์ของข้อความค้นหานั้นชัดเจนยิ่งขึ้น คอลัมน์ที่แอปพลิเคชันใช้นั้นชัดเจน
  • เป็นไปตามกฎโมดูลาร์เกี่ยวกับการใช้การพิมพ์ที่เข้มงวดทุกครั้งที่ทำได้ Explicit เกือบจะดีกว่าในระดับสากล

สรุป


ขาดความคุ้นเคยและ / หรือความสะดวกสบายฉันไม่เห็นประโยชน์ใด ๆ ที่จะใช้อนุประโยค ANSI-89 WHERE ต่อไปแทนไวยากรณ์ ANSI-92 JOIN บางคนอาจบ่นว่าไวยากรณ์ ANSI-92 นั้นละเอียดกว่า แต่นั่นคือสิ่งที่ทำให้มันชัดเจน ยิ่งชัดเจนมากเท่าไหร่ก็ยิ่งเข้าใจและดูแลรักษาได้ง่ายขึ้นเท่านั้น


14
"... การสืบค้นใด ๆ ที่เกี่ยวข้องกับตารางมากกว่าหนึ่งตารางจำเป็นต้องมีการเชื่อมโยงบางรูปแบบเพื่อเชื่อมโยงผลลัพธ์จากตาราง 'A' ไปยังตาราง 'B' ... มิฉะนั้นคุณจะได้รับ Cartesian Product และคุณอาจไม่ต้องการสิ่งนั้น (Cartesians เหล่านั้นทำผลิตภัณฑ์ LOUSY)
Scott Smith

8

คนส่วนใหญ่มักจะพบว่าไวยากรณ์ของ JOIN ชัดเจนขึ้นเล็กน้อยว่ากำลังเข้าร่วมกับอะไร นอกจากนี้ยังมีประโยชน์ในการเป็นมาตรฐาน

โดยส่วนตัวแล้วฉัน "โตขึ้น" ใน WHERE แต่ยิ่งฉันใช้ไวยากรณ์ JOIN มากเท่าไหร่ฉันก็เริ่มเห็นว่ามันชัดเจนมากขึ้น


1
@nawfal ฉันเข้าใจ - ฉันถูกนำมาใช้กับไวยากรณ์แบบเก่า แต่เมื่อฉันคุ้นเคยกับรูปแบบใหม่ประโยชน์ก็ชัดเจนขึ้นเช่นการเข้าร่วมข้ามยากขึ้นโดยไม่ได้ตั้งใจชัดเจนมากขึ้นดูง่ายขึ้นว่าอะไรคือการเข้าร่วมและอะไร ฟิลเตอร์ ฯลฯ ... ฉันติดยาเสพติด
พื้นฐาน

8

นี่คือปัญหาในการใช้ไวยากรณ์ where (อื่น ๆ ที่เรียกว่าการเข้าร่วมโดยนัย):

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

การรวมด้านขวาและด้านซ้ายเป็นปัญหา (ในเซิร์ฟเวอร์ SQl คุณไม่รับประกันว่าจะได้ผลลัพธ์ที่ถูกต้อง) ในไวยากรณ์เก่าในบางฐานข้อมูล นอกจากนี้ยังเลิกใช้งานใน SQL Server ที่ฉันรู้จัก

หากคุณตั้งใจจะใช้การรวมแบบไขว้นั่นจะไม่ชัดเจนจากไวยากรณ์แบบเก่า เป็นที่ชัดเจนโดยใช้มาตรฐาน ANSII ปัจจุบัน

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

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

จริงๆแล้วคุณจะใช้รหัสประเภทอื่นที่ถูกแทนที่ด้วยวิธีการที่ดีกว่าเมื่อ 18 ปีก่อนหรือไม่?


6

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


3

คุณไม่สามารถใช้ WHERE เพื่อรวมสองตารางได้ สิ่งที่คุณทำได้คือเขียน:

SELECT * FROM A, B
WHERE ...

ลูกน้ำที่นี่เทียบเท่ากับการเขียน:

SELECT *
FROM A
CROSS JOIN B
WHERE ...

คุณจะเขียนว่า? ไม่ - เพราะมันไม่ใช่สิ่งที่คุณหมายถึงเลย คุณไม่ต้องการเข้าร่วมข้ามคุณต้องการเข้าร่วมภายใน แต่เมื่อคุณเขียนลูกน้ำคุณกำลังพูดว่า CROSS JOIN และนั่นทำให้สับสน


0

จริงๆแล้วคุณมักต้องการทั้ง "WHERE" และ "JOIN"

"JOIN" ใช้เพื่อดึงข้อมูลจากตารางสองตารางโดยอิงตามค่าของคอลัมน์ทั่วไป หากคุณต้องการกรองผลลัพธ์นี้เพิ่มเติมให้ใช้คำสั่ง WHERE

ตัวอย่างเช่น "LEFT JOIN" จะดึงข้อมูลทุกแถวจากตารางด้านซ้ายรวมทั้งแถวที่ตรงกันจากตารางด้านขวา แต่ไม่ได้กรองเรกคอร์ดตามค่าเฉพาะหรือในคอลัมน์อื่น ๆ ที่ไม่ได้เป็นส่วนหนึ่งของ JOIN ดังนั้นหากคุณต้องการกรองผลลัพธ์นี้เพิ่มเติมให้ระบุตัวกรองเพิ่มเติมในส่วนคำสั่ง WHERE

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