यहां दो अलग-अलग समाधान दिए गए हैं:(नोट:मैंने एनम फ़ील्ड को "package_type" कहा है)
पहला समाधान (IF() फ़ंक्शन के माध्यम से):
select
i.location,
if(ps.id is not null, ps.id, pg.id) as package_id
from
(select distinct location from Items) i
inner join
(select i.location, p.id
from Items i
inner join Packages p on (i.package_id = p.id and p.package_type = 'general')
) pg on (i.location = pg.location)
left join
(select i.location, p.id
from Items i
inner join Packages p on (i.package_id = p.id and p.package_type = 'special')
) ps on (i.location = ps.location)
यह समाधान अनिवार्य रूप से स्थान लेता है और इसे सामान्य के साथ पैकेज में जोड़ता है (जिसे अस्तित्व में माना जाता है; इसलिए inner join
) और विशेष पैकेज (जो वैकल्पिक है; इसलिए left join
) यह इस तरह के रिकॉर्ड बनाता है:
location | general-package | [special-package]
इसके बाद यह MySQL IF
. का उपयोग करता है पहले विशेष पैकेज की आईडी चुनने का प्रयास करने के लिए कार्य करता है, और फिर सामान्य पैकेज की आईडी पर वापस आ जाता है।
दूसरा समाधान (एनम को पूर्णांक में डालने के माध्यम से):
select i.location, p.id
from
(select i.location, max(cast(package_type as unsigned)) as package_type
from Items i
left join Packages p on (i.package_id = p.id)
group by location
) i
inner join
(select i.location, p.id, p.package_type
from Items i
inner join Packages p on (i.package_id = p.id)
) p on (i.location = p.location and i.package_type = p.package_type)
यह समाधान इस तथ्य का फायदा उठाता है कि एनम को पूर्णांक के रूप में संग्रहीत किया जाता है। यह एनम को एक पूर्णांक में रखता है। special
इस मामले में 2
लौटाएगा और general
वापस आ जाएगा 1
. चूंकि ये विशेष इस मामले में सामान्य से अधिक होने की गारंटी है (अर्थात 2> 1), हम MAX
का उपयोग कर सकते हैं कुल समारोह। अब हमारे पास अनिवार्य रूप से स्थानों और उनके "अनुशंसित पैकेज" की एक तालिका है (यानी विशेष यदि यह मौजूद है, अन्यथा सामान्य)। हम इसे सामान्य क्वेरी के साथ अपेक्षित पैकेज प्रकार के साथ जोड़ते हैं, और यह सही परिणाम देता है।
अस्वीकरण:मैं इन विधियों में से किसी की भी प्रभावशीलता के बारे में निश्चित नहीं हूं, इसलिए आप स्वयं इसका परीक्षण करना चाह सकते हैं।
यदि आप तालिका को फिर से डिज़ाइन करना चाहते हैं या दक्षता के लिए इसे असामान्य बनाना चाहते हैं, तो मुझे लगता है कि यह डिज़ाइन अधिक उपयुक्त हो सकता है:
GeneralPackages table
id, name
1, General Package 1
SpecialPackages table
id, name
1, Special Package 1
2, Special Package 2
Items table
id, general_package_id, special_package_id, location
1, 1, NULL, America
2, 1, 2, Europe
इसका फायदा यह होगा कि डेटाबेस स्तर पर कई नियमों को लागू करना आसान होता है:
- किसी स्थान में हमेशा एक सामान्य पैकेज होना चाहिए (Items.general_package_id को NOT NULL के रूप में परिभाषित किया जा सकता है)
- किसी स्थान में केवल एक ही सामान्य पैकेज होना चाहिए (जोड़ने की गारंटी के बजाय इसे एक फ़ील्ड में जोड़ना है कि केवल एक निर्दिष्ट है)
- एक स्थान में अधिकतम एक विशेष पैकेज हो सकता है (जोड़ने की गारंटी के बजाय इसे एक क्षेत्र में जोड़ना सुनिश्चित करता है कि केवल एक ही निर्दिष्ट है)
- Items.general_package_id =GeneralPackages.id पर एक विदेशी कुंजी इस बात की गारंटी देगी कि उस कॉलम में केवल वैध पैकेज हैं जो "सामान्य" हैं।
- विशेष_पैकेज_आईडी के लिए भी यही किया जा सकता है।
नुकसान यह होगा कि हर बार जब आप अपने पुराने प्रश्नों में से किसी एक का उपयोग करते हैं तो आपको शायद यूनियन का उपयोग करने की आवश्यकता होगी।