1052: คอลัมน์ 'id' ในรายการฟิลด์ไม่ชัดเจน


99

ฉันมี 2 โต๊ะ tbl_namesและtbl_sectionซึ่งมีทั้งidสนามอยู่ในนั้น ฉันจะเลือกidฟิลด์ได้อย่างไรเพราะฉันมักจะได้รับข้อผิดพลาดนี้:

1052: Column 'id' in field list is ambiguous

นี่คือคำถามของฉัน:

SELECT id, name, section
  FROM tbl_names, tbl_section 
 WHERE tbl_names.id = tbl_section.id

ฉันสามารถเลือกฟิลด์ทั้งหมดและหลีกเลี่ยงข้อผิดพลาดได้ แต่นั่นจะเป็นการเสียประสิทธิภาพ ฉันควรทำอย่างไรดี?

คำตอบ:


156

SQL สนับสนุนการกำหนดคอลัมน์โดยนำหน้าการอ้างอิงด้วยชื่อเต็มของตาราง:

SELECT tbl_names.id, tbl_section.id, name, section
  FROM tbl_names
  JOIN tbl_section ON tbl_section.id = tbl_names.id 

... หรือนามแฝงของตาราง:

SELECT n.id, s.id, n.name, s.section
  FROM tbl_names n
  JOIN tbl_section s ON s.id = n.id 

นามแฝงของตารางเป็นแนวทางที่แนะนำ - ทำไมต้องพิมพ์มากกว่าที่คุณต้องทำ?

เหตุใดข้อความค้นหาเหล่านี้จึงดูแตกต่างกัน

ประการที่สองคำตอบของฉันใช้ไวยากรณ์ ANSI-92 JOIN (ของคุณคือ ANSI-89) ในขณะที่ดำเนินการเหมือนกันไวยากรณ์ ANSI-89 ไม่สนับสนุนการรวม OUTER (ขวา, ซ้าย, เต็ม) ไวยากรณ์ ANSI-89 ควรได้รับการพิจารณาว่าเลิกใช้แล้วมี SO จำนวนมากที่จะไม่ลงคะแนนให้ไวยากรณ์ ANSI-89 เพื่อเสริมสร้าง สำหรับข้อมูลเพิ่มเติมโปรดดูคำถามนี้


งง! เนื่องจากไม่มีสิ่งใดถูกลบออกจากภาษา SQL จริง SQL-89 จึงเป็นชุดย่อยที่เหมาะสมของ SQL-92 ไวยากรณ์ของ OP เป็นไวยากรณ์ SQL-92 ที่ถูกต้อง (และถ้าฉันไม่ได้ทำอะไรบางอย่างของคุณเป็นไวยากรณ์ SQL-89 ที่ถูกต้อง) ผมคิดว่าINNER JOINจะเป็น 'คิดค่าเสื่อมราคาตั้งแต่ SQL-92 NATURAL JOINแนะนำ
61

17

ในSELECTคำสั่งของคุณคุณต้องนำหน้า id ของคุณด้วยตารางที่คุณต้องการเลือก

SELECT tbl_names.id, name, section 
FROM tbl_names
INNER JOIN tbl_section 
   ON tbl_names.id = tbl_section.id

หรือ

SELECT tbl_section.id, name, section 
FROM tbl_names
INNER JOIN tbl_section 
   ON tbl_names.id = tbl_section.id

สิ่งนี้จะส่งคืนเพียงหนึ่งในidฟิลด์ สถานะ OP "เพียงแค่เลือกฟิลด์ทั้งหมดและหลีกเลี่ยงข้อผิดพลาด" และฉันไม่ลงคะแนนสำหรับไวยากรณ์ ANSI-89
OMG Ponies

เห็นด้วย แต่คำถามคือวิธีการเลือกฟิลด์ id
Taryn

6

คุณสามารถทำได้โดยระบุชื่อที่มีคุณสมบัติครบถ้วนเช่น:

SELECT tbl_names.id as id, name, section FROM tbl_names, tbl_section WHERE tbl_names.id = tbl_section.id

ซึ่งจะให้ id ของ tbl_names


ดูความคิดเห็นของฉันต่อคำตอบของ bluefeet
OMG Ponies

ไม่ใช่ "ชื่อที่มีคุณสมบัติครบถ้วน" แต่เป็นตัวแปรช่วง เมื่อคุณละตัวแปรช่วงที่ชัดเจน SQL จะสร้างตัวแปรที่เหมือนกับชื่อตาราง เพื่อให้ดูดีขึ้นว่าฉันหมายถึงอะไรให้เปลี่ยนFROMอนุประโยคของคุณ...FROM tbl_names tbl_names, tbl_section tbl_section WHERE...- นั่นคือสิ่งที่ตัวแยกวิเคราะห์ทำเพื่อสร้างตัวแปรช่วง
61

4

ทางออกที่ง่ายที่สุดคือการเข้าร่วมกับผู้แทนUSING ONด้วยวิธีนี้ฐานข้อมูลจะ "รู้" ว่าทั้งสองidคอลัมน์เหมือนกันและจะไม่คิดในสิ่งนั้น:

SELECT id, name, section
  FROM tbl_names
  JOIN tbl_section USING (id)

หากidเป็นเพียงชื่อคอลัมน์ทั่วไปในtbl_namesและtbl_sectionคุณยังสามารถใช้NATURAL JOIN:

SELECT id, name, section
  FROM tbl_names
  NATURAL JOIN tbl_section

ดูเพิ่มเติม: https://dev.mysql.com/doc/refman/5.7/en/join.html


3

สิ่งที่คุณอาจต้องการทำที่นี่คือใช้ตัวดำเนินการสหภาพเช่นนี้:

(select ID from Logo where AccountID = 1 and Rendered = 'True')
  union
  (select ID from Design where AccountID = 1 and Rendered = 'True')
  order by ID limit 0, 51

นี่คือเอกสารสำหรับมันhttps://dev.mysql.com/doc/refman/5.0/en/union.html


3

มีคำตอบมากมายสำหรับคำถามของคุณคุณสามารถทำเช่นนี้ได้เช่นกัน คุณสามารถตั้งชื่อนามแฝงให้ตารางของคุณและใช้ในคิวรีแบบเลือกดังนี้:

SELECT a.id, b.id, name, section
FROM tbl_names as a 
LEFT JOIN tbl_section as b ON a.id = b.id;

0

หากรูปแบบของ id ในสองตารางแตกต่างกันคุณต้องการเข้าร่วมด้วยเช่นนี้คุณสามารถเลือกใช้ id จากตารางหลักเดียวได้โดยระบุว่าคุณมีtable_customesและtable_ordersและ tha id สำหรับออเดอร์เหมือนกับ " 101 " " 102 " ... " 110 " ใช้เพียงอันเดียวสำหรับลูกค้า

select customers.id, name, amount, date from customers.orders;

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