2009-02-09 22 views
17

मैं innertable.id = outertable.id निर्दिष्ट करके आंतरिक क्वेरी पर WHERE स्थिति प्रदान करना चाहता हूं। हालांकि, MySQL (5.0.45) रिपोर्ट करता है "अज्ञात कॉलम 'outertable.id' 'जहां खंड' 'में। क्या इस प्रकार की क्वेरी संभव है?जॉइन सिंटैक्स में MySQL सहसंबंधित सबक्वायरी

आंतरिक क्वेरी ग्रुप BY का उपयोग करके कॉलम पर पंक्तियों को पिवोट कर रही है। यह पूरी तरह से बाहरी क्वेरी में किया जा सकता है, लेकिन अतिरिक्त जुड़ने के कारण संभवतः अतिरिक्त ओवरहेड लगाना होगा।

वैकल्पिक रूप से, मैं आंतरिक क्वेरी में WHERE स्थिति को छोड़ सकता हूं और इसके बजाय एक बाहरी outabletable.id = innerquery.id निर्दिष्ट कर सकता हूं, लेकिन फिर यह पूरे आंतरिक क्वेरी पंक्ति को फिर से बाहरी में शामिल करने के लिए लाएगा, जो अक्षम है।

वास्तविक एसक्यूएल नीचे दिखाई देता है:

select t.ticketid, u.userid, t.fullname, u.loginapi_userid, t.email, tp.subject, tp.contents, a.PhoneNumber, a.Location, a.Extension, a.BusinessUnit, a.Department 
from swtickets t 
inner join swticketposts tp on t.ticketid = tp.ticketid 
inner join swusers u on t.userid = u.userid 
left join 
    (
    select 
    cfv.typeid, 
    min(case cfv.customfieldid when 1 then cfv.fieldvalue end) as 'PhoneNumber', 
    min(case cfv.customfieldid when 3 then cfv.fieldvalue end) as 'Location', 
    min(case cfv.customfieldid when 5 then cfv.fieldvalue end) as 'Extension', 
    min(case cfv.customfieldid when 8 then cfv.fieldvalue end) as 'BusinessUnit', 
    min(case cfv.customfieldid when 9 then cfv.fieldvalue end) as 'Department' 
    from swcustomfieldvalues cfv 
    where cfv.typeid = t.ticketid 
    group by cfv.typeid 
) as a on 1 = 1 
where t.ticketid = 2458; 
+2

मेरा मूल प्रश्न है, "क्या इस प्रकार की क्वेरी संभव है?" (MySQL 5.0 के संबंध में)। एप्लिकेशन कोड पर स्कीमा या स्केलपिंग बदलना प्रश्न विषय के बाहर है। –

उत्तर

29

आपके प्रश्न का उत्तर नहीं है, जैसा कि आप कर रहे हैं सहसंबंध नामों का संदर्भ देना संभव नहीं है। बाहरी क्वेरी में शामिल होने से पहले व्युत्पन्न तालिका आपकी आंतरिक क्वेरी द्वारा उत्पादित की जाती है।तो t, tp, और u जैसे सहसंबंध नाम आंतरिक क्वेरी के लिए उपलब्ध नहीं हैं।

इसे हल करने के लिए, मैं आंतरिक क्वेरी में एक ही निरंतर पूर्णांक मान का उपयोग करने की अनुशंसा करता हूं, और फिर 1=1 की बजाय वास्तविक स्थिति का उपयोग करके बाह्य क्वेरी में व्युत्पन्न तालिका में शामिल हों।

SELECT t.ticketid, u.userid, t.fullname, u.loginapi_userid, t.email, 
    tp.subject, tp.contents, a.PhoneNumber, a.Location, a.Extension, 
    a.BusinessUnit, a.Department 
FROM swtickets t 
INNER JOIN swticketposts tp ON (t.ticketid = tp.ticketid) 
INNER JOIN swusers u ON (t.userid = u.userid) 
LEFT OUTER JOIN (
    SELECT cfv.typeid, 
    MIN(CASE cfv.customfieldid WHEN 1 THEN cfv.fieldvalue END) AS 'PhoneNumber', 
    MIN(CASE cfv.customfieldid WHEN 3 THEN cfv.fieldvalue END) AS 'Location', 
    MIN(CASE cfv.customfieldid WHEN 5 THEN cfv.fieldvalue END) AS 'Extension', 
    MIN(CASE cfv.customfieldid WHEN 8 THEN cfv.fieldvalue END) AS 'BusinessUnit', 
    MIN(CASE cfv.customfieldid WHEN 9 THEN cfv.fieldvalue END) AS 'Department' 
    FROM swcustomfieldvalues cfv 
    WHERE cfv.typeid = 2458 
    GROUP BY cfv.typeid 
) AS a ON (a.typeid = t.ticketid) 
WHERE t.ticketid = 2458; 
0

मेरे सुझाव है कि तुम क्या दक्षता के आधार पर की संभावना से इनकार किया जा रहा था। जैसे जहां खंड और एक जॉइन का उपयोग करना (टी.ticketid = a.ticketid के अनुसार)

क्या आप कुछ ठोस उदाहरणों से अक्षमता पर अपने विचार साबित करने में सक्षम हैं? मुझे पता है कि आप क्या कह रहे हैं लेकिन बाहरी क्वेरी में हर पंक्ति का उपयोग करने वाली किसी भी विधि को आंतरिक क्वेरी में प्रत्येक पंक्ति में शामिल किया जा रहा है, इसलिए निष्पादन योजना के आधार पर यह आपके लिए संदेह के रूप में अक्षम नहीं हो सकता है?

0

मुझे लगता है कि समस्या 'cfv.typeid = t.ticketid' है तो? इसके बारे में मेरी सोच यह होगी कि, जबकि MySQL सहसंबंधित सबक्वायरीज़ का समर्थन करता है, आप जो करने की कोशिश कर रहे हैं, ऐसा लगता है कि यह शामिल होने में असफल हो सकता है क्योंकि 'आंतरिक' क्वेरी वास्तव में बाकी की क्वेरी के अंदर 'अंदर' नहीं है एक WHERE खंड में। लेकिन ऐसा लगता है कि आप सबक्वायरी से बाहर निकलने वाले खंड को ले सकते हैं और a.typeid = t.ticketid पर अपनी जॉइन स्थिति बना सकते हैं।

+0

क्षमा करें, यह क्वेरी के किसी अन्य भिन्नता से बचे हुए थे। इसका उत्पादन होने वाली वास्तविक त्रुटि से कोई लेना देना नहीं था, इसलिए मैंने इसे ऊपर दिए गए प्रश्न से हटा दिया है। वास्तव में –

1

मैं इसे कई जोड़ों के साथ लिखूंगा। जब आप कहते हैं कि यह "अतिरिक्त ओवरहेड लेगा" जो मुझे बताता है कि आपने यह सुनिश्चित करने के लिए इसका परीक्षण नहीं किया है। यदि आपके पास सभ्य अनुक्रमणिका हैं तो जुड़ना बहुत छोटा होना चाहिए।

यह जेनेरिक "सब कुछ पकड़ो" टेबल डिज़ाइन पैटर्न के केवल एक नुकसान को दिखाता है।

+1

। डिजाइन को एंटीटी-एट्रिब्यूट-वैल्यू कहा जाता है। यह कई तरीकों से सामान्यीकरण को तोड़ता है, और इसका उपयोग करना बहुत मुश्किल है। –

+0

आंतरिक क्वेरी (सीएफवी) में "WHERE cfv.typeid = 2458" का उपयोग करके इंडेक्स की साधारण कमी के कारण सीएफवी पर एक खराब टेबल स्कैन का कारण बनता है, हालांकि, इस स्थिति को छोड़कर चीजों को और भी बदतर बना दिया जाता है क्योंकि "अस्थायी का उपयोग करना; फाइलों का उपयोग करना "व्युत्पन्न क्वेरी पर एक अतिरिक्त तालिका स्कैन के अतिरिक्त। –

+0

मुझे यकीन नहीं है कि "आंतरिक क्वेरी" से आपका क्या मतलब है। वहां 5 नए आंतरिक शामिल होंगे, तो हो सकता है कि आपका यही मतलब हो। मुझे आशा है कि आपकी सीएफवी तालिका में टाइपिड पर एक इंडेक्स होगा। मैं शायद उस क्रम में टाइपिड और कस्टमफील्ड पर क्लस्टर्ड इंडेक्स रखूंगा। –

2

आप एंटिटी-एट्रिब्यूट-वैल्यू डिज़ाइन का उपयोग कर रहे हैं, और अंततः पारंपरिक परिणाम सेट जेनरेट करने का प्रयास करते समय इस स्केलेबल को बनाने का कोई तरीका नहीं है। एक प्रश्न में ऐसा करने की कोशिश मत करो।

इसके बजाय, अपने सामान्यीकृत टेबल पहले क्वेरी:

SELECT t.ticketid, u.userid, t.fullname, u.loginapi_userid, t.email, 
    tp.subject, tp.contents 
FROM swtickets t 
INNER JOIN swticketposts tp ON (t.ticketid = tp.ticketid) 
INNER JOIN swusers u ON (t.userid = u.userid) 
WHERE t.ticketid = 2458; 

तो परिणाम सेट की अनेक पंक्तियां पर परिणाम के साथ, अपने कस्टम क्षेत्रों क्वेरी:

SELECT cfv.customfieldid, cfv.fieldvalue 
FROM swcustomfieldvalues cfv 
WHERE cfv.typeid = 2458; 

आप में अनेक पंक्तियों मिल जाएगा परिणाम सेट, प्रत्येक कस्टम फ़ील्ड के लिए एक पंक्ति:

+---------------+--------------+ 
| customfieldid | fieldvalue | 
+---------------+--------------+ 
|    1 | 415-555-1234 | 
|    3 | Third office | 
|    5 | 123   | 
|    8 | Support  | 
|    9 | Engineering | 
+---------------+--------------+ 

आपको आवेदन लिखने की आवश्यकता है एक लूप में अनुप्रयोग ऑब्जेक्ट फ़ील्ड में परिणाम-सेट फ़ील्ड को मैप करने के लिए कोड।

इस तरह से एक इकाई-विशेषता-मूल्य तालिका का उपयोग प्रदर्शन और कोड रखरखाव के मामले में अधिक स्केलेबल है।

+0

यह सुझाव मूल प्रश्न क्वेरी के समान ही पूरा हो रहा है ("cfv.typeid = t.ticketid" कहां बदलें "जहां cfv.typeid = 2458"); इसके बजाय, यह पिवट को करने के लिए डेटाबेस के बाहर कोड पर निर्भर करता है। –

+0

हां, बिल्कुल। ईएवी के मामले में, इसे एक प्रश्न में कुशल बनाने का कोई तरीका नहीं है। आपको आवेदन कोड में पिवट करना चाहिए। –

संबंधित मुद्दे