कुंजी, ज़ाहिर है, दो तालिकाओं के बीच जुड़ना है। समझने में मदद करने के लिए, मैं इसे पूरी क्वेरी के बजाय पहले अलग से दिखाता हूं। प्रत्येक आइटम के लिए, हम सभी बॉक्स आकार ढूंढते हैं जो आइटम को समायोजित कर सकते हैं।
सभी मामलों में, मिलान संभव है यदि उत्पाद की ऊंचाई <=बॉक्स की ऊंचाई, और अन्य दो आयाम किसी भी क्रमपरिवर्तन में फिट होते हैं (उत्पादों को हमेशा घुमाया जा सकता है बॉक्स में फिट होने के लिए, चाहे वे लेटने योग्य हों या नहीं)।
केवल लेएबल उत्पादों के लिए, हमें उत्पाद को तीनों आयामों में घुमाने की अनुमति है ताकि उन्हें बक्सों में फिट किया जा सके। इसका मतलब यह है कि, केवल ले जाने योग्य उत्पादों के लिए, हम उत्पाद की चौड़ाई या गहराई की तुलना बॉक्स की ऊंचाई से कर सकते हैं, और उत्पाद के शेष दो आयामों की तुलना बॉक्स की चौड़ाई और गहराई से कर सकते हैं।
एक बार जब हम समझ जाते हैं कि मैंने अभी क्या कहा (जिस तरह से हम इसे कंप्यूटर के बिना करेंगे, तो बस कागज पर पेंसिल के साथ), कोड में अनुवाद लगभग स्वचालित है:
select p.id, b.box_size
from products p left outer join boxes b
on
p.h <= b.h and least (p.w, p.d) <= least (b.w, b.d)
and greatest(p.w, p.d) <= greatest(b.w, b.d)
or
p.layable = 'y'
and
( p.w <= b.h and least (p.h, p.d) <= least (b.w, b.d)
and greatest(p.h, p.d) <= greatest(b.w, b.d)
or
p.d <= b.h and least (p.w, p.h) <= least (b.w, b.d)
and greatest(p.w, p.h) <= greatest(b.w, b.d)
)
;
आउटपुट:
ID BOX_SIZE
--- --------
a S
a M
a L
b M
b L
c L
d S
d M
d L
e L
f L
g S
g M
g L
h M
h L
i L
j
प्रत्येक उत्पाद के लिए, हमें वे सभी आकार मिले जो काम करेंगे।
किसी भी बॉक्स आकार में फिट नहीं होने वाले उत्पादों को शामिल करने के लिए क्वेरी में बाहरी जुड़ाव पर ध्यान दें; यह उत्पाद j
. का मामला है , जो आउटपुट के अंत में दिखाई देता है। ध्यान दें कि मैं null
. का उपयोग करता हूं "उपलब्ध नहीं . के लिए मार्कर के रूप में " - "उपलब्ध नहीं" शब्द null
. के सरल उपयोग पर कोई मूल्यवान जानकारी नहीं जोड़ते हैं ।
अगला चरण एक साधारण एकत्रीकरण है - प्रत्येक उत्पाद के लिए, काम करने वाले सबसे छोटे आकार का पता लगाएं। इसके लिए सबसे अच्छा टूल है FIRST
कुल समारोह (जैसा कि नीचे इस्तेमाल किया गया है)। हमें बॉक्स के आकार के अनुसार ऑर्डर करना चाहिए; चूंकि आकार एस, एम, एल हैं (जो केवल दुर्घटना से विपरीत वर्णमाला क्रम में हैं), मैं decode()
का उपयोग करता हूं 1 को S, 2 से M, 3 से L असाइन करने के लिए कार्य करता है। समग्र क्वेरी "पहला" आकार ढूंढती है जो प्रत्येक उत्पाद के लिए काम करता है।
यहां महत्वपूर्ण बात यह है कि क्वेरी को किसी भी संभावित "बॉक्स आकार" में आसानी से सामान्यीकृत किया जा सकता है - भले ही सभी तीन आयाम बढ़ते क्रम में न हों। (आपके पास केवल एक आयाम वाले बक्से बहुत बड़े हो सकते हैं जबकि अन्य छोटे हैं, आदि)। आप बॉक्स वॉल्यूम के अनुसार ऑर्डर कर सकते हैं, या आप बॉक्स टेबल में स्टोर कर सकते हैं वरीयता का एक क्रम, जो मैं decode()
. के साथ क्वेरी में करता हूं, के बराबर है समारोह।
अंत में, क्वेरी और आउटपुट इस तरह दिखते हैं। ध्यान दें कि मैंने nvl()
. का इस्तेमाल किया है select
. में 'not available'
. उत्पन्न करने के लिए क्लॉज अंतिम आइटम के लिए, यदि आपको वास्तव में इसकी आवश्यकता है (जिस पर मुझे संदेह है, लेकिन यह मेरी व्यावसायिक समस्या नहीं है।)
select p.id,
nvl( min(b.box_size) keep (dense_rank first
order by decode(b.box_size, 'S', 1, 'M', 2, 'L', 3))
, 'not available') as box_size
from products p left outer join boxes b
on
p.h <= b.h and least (p.w, p.d) <= least (b.w, b.d)
and greatest(p.w, p.d) <= greatest(b.w, b.d)
or
p.layable = 'y'
and
( p.w <= b.h and least (p.h, p.d) <= least (b.w, b.d)
and greatest(p.h, p.d) <= greatest(b.w, b.d)
or
p.d <= b.h and least (p.w, p.h) <= least (b.w, b.d)
and greatest(p.w, p.h) <= greatest(b.w, b.d)
)
group by p.id
;
ID BOX_SIZE
--- --------
a S
b M
c L
d S
e L
f L
g S
h M
i L
j not available