แบบสอบถามย่อยสำหรับการดึงชื่อตาราง

ฉันมีคำถามเช่นนี้:

SELECT * FROM (SELECT linktable FROM adm_linkedfields WHERE name = 'company') as cbo WHERE group='BEST'

โดยพื้นฐานแล้ว ชื่อตารางสำหรับการสืบค้นหลักจะถูกดึงมาจากแบบสอบถามย่อย

ฉันได้รับข้อผิดพลาดที่ #1054 - Unknown column 'group' in 'where clause'

เมื่อฉันตรวจสอบ (ลบคำสั่ง Where ออก) ฉันพบว่าแบบสอบถามส่งคืนเฉพาะผลลัพธ์ของแบบสอบถามย่อยตลอดเวลา

ตารางแบบสอบถามย่อย adm_linkedfields มีโครงสร้าง id | name | linktable

ขณะนี้กำลังใช้ MySQL กับ PDO แต่แบบสอบถามควรเข้ากันได้กับฐานข้อมูลหลัก (ได้แก่ Oracle, MSSQL, PgSQL และ MySQL)

อัปเดต: แบบสอบถามย่อยควรส่งคืนชื่อของตารางสำหรับแบบสอบถามหลัก ในกรณีนี้มันจะส่งคืน tbl_company

ตาราง tbl_company สำหรับการสืบค้นหลักมีโครงสร้างดังนี้ : id | name | group

ขอบคุณล่วงหน้า.


person Ravi    schedule 23.06.2013    source แหล่งที่มา
comment
ดูคำตอบของฉันด้วยเหตุผลของข้อผิดพลาด BTW จากที่มาของกลุ่มคอลัมน์ .. ไม่ได้อยู่ในคำจำกัดความตารางของคุณ ?? และมันเป็น DT ไม่ใช่ SubQ   -  person cosmos    schedule 23.06.2013
comment
ทำไมต้องลงคะแนนเสียง? ขอบคุณถ้ามีเหตุผลที่ให้ไว้   -  person Ravi    schedule 23.06.2013
comment
@ user2407394 เขาเรียกคอลัมน์กลุ่มในส่วนคำสั่ง WHERE แต่แบบสอบถามย่อยส่งคืนเพียงคอลัมน์เดียวที่เรียกว่า linktable   -  person Jakub Kania    schedule 23.06.2013
comment
@jakub: มันคือ DT ไม่ใช่ subQ เขาอัปเดตคำถามหลังจากความคิดเห็นของฉัน .. @ Ravi: ขอบคุณสำหรับการอัปเดต ตอนนี้ฉันเข้าใจสิ่งที่คุณต้องการจะทำ ฉันมักจะเห็นด้วยกับคำตอบของจาคุบ -1 เกิดจากการขาดรายละเอียด การถอดมัน   -  person cosmos    schedule 23.06.2013


คำตอบ (3)


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

person Jakub Kania    schedule 23.06.2013
comment
ขอบคุณจาคุบ. ฉันเพิ่งทำอย่างนั้น ต้องการทราบว่าฉันสามารถทำได้ในแบบสอบถามเดียวมากกว่าการโทรสองครั้งหรือไม่ - person Ravi; 23.06.2013

นี่คือปัญหา:

SELECT * FROM (SELECT linktable FROM adm_linkedfields WHERE name = 'company') as cbo 
WHERE group='BEST';

คุณกำลังเลือกจาก DT ซึ่งมีคอลัมน์ "linktable" เพียงคอลัมน์เดียว ดังนั้นคุณจะไม่สามารถใส่คอลัมน์อื่นใดไว้ในตำแหน่งคำสั่งย่อยของบล็อกภายนอกได้ คิดในแง่ของบล็อกการเลือกภายนอกอ้างอิง DT ซึ่งมีเพียงคอลัมน์เดียว

ปัญหาของคุณคล้ายกันเมื่อคุณพยายามทำ:

create table t1(x1 int);
select * from t1 where z1 = 7;  //error
person cosmos    schedule 23.06.2013
comment
ขอบคุณ. ฉันมีชื่อตารางเก็บไว้ในตารางอื่น (ซึ่งกำลังพยายามดึงข้อมูลผ่านแบบสอบถามย่อย) และต้องการส่งคืนแถวทั้งหมดจากตารางนั้น ฉันได้ให้โครงสร้างตารางเป้าหมายของฉันในการอัปเดตหากอาจช่วยได้ - person Ravi; 23.06.2013

คำถามของคุณคือ:

SELECT *
FROM (SELECT linktable
      FROM adm_linkedfields
      WHERE name = 'company'
     ) cbo
WHERE group='BEST'

อันดับแรก หากคุณสนใจความเข้ากันได้ข้ามฐานข้อมูล อย่าตั้งชื่อคอลัมน์หรือตารางตามคำสงวนของ SQL group เป็นชื่อคอลัมน์ที่แย่มาก

ประการที่สอง ส่วนคำสั่ง from ส่งคืนตารางที่มีรายการชื่อ (ของตาราง แต่ไม่เกี่ยวข้อง) ไม่มีคอลัมน์ชื่อ group นั่นคือปัญหาที่คุณประสบ

คุณจะทำอย่างไรเพื่อแก้ไขปัญหานี้? วิธีแก้ปัญหาที่ไร้เดียงสาคือการเรียกใช้แบบสอบถามย่อย เรียกใช้ และใช้ชื่อตารางผลลัพธ์ในคำสั่งไดนามิกเพื่อดำเนินการแบบสอบถามที่คุณต้องการ

ปัญหาพื้นฐานคือโครงสร้างข้อมูลของคุณ โดยทั่วไปการมีตารางหลายตารางที่มีโครงสร้างเดียวกันมักเป็นสัญญาณของการออกแบบที่ไม่ดี โดยพื้นฐานแล้วคุณมีสองทางเลือก

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

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

create view vw_linktable as
    select 'table1' as which, t.* from table1 t union all
    select 'table2', t.* from table2 t

นอกจากนี้ยังเข้ากันได้กับฐานข้อมูลทั้งหมด

person Gordon Linoff    schedule 23.06.2013