2013-09-30 10 views
7

पर आधारित सशर्त चयन मेरे पास एक सारणी है जिसमें तीन अलग-अलग फ़ाइल प्रकार हो सकते हैं। यदि फ़ाइल प्रकार ए मौजूद है, तो ए का चयन करें, अन्यथा यदि फ़ाइल प्रकार बी मौजूद है और उसी क्लाइंट_आईडी के साथ कोई प्रकार नहीं है, तो बी का चयन करें, अन्य प्रकार का चयन करें सी
कुछ अन्य जादू बाद में होगा जो चयनित फ़ाइल को हटा देगा मेज से।कॉलम मान

मैं एक Oracle 10g SQL डेटाबेस में निम्न तालिका:

ID | TYPE | CLIENT_ID 
######################## 
file1 | A | 1 
file2 | B | 1 
file3 | C | 1 
file4 | B | 2 

और जो लोग घर, sqlfidde या एसक्यूएल में साथ पालन करना चाहते हैं के लिए:

create table files (
    id varchar(8) primary key, 
    type varchar(4), 
    client_id number 
); 
insert into files values ('file1', 'A', 1); 
insert into files values ('file2', 'B', 1); 
insert into files values ('file3', 'C', 1); 
insert into files values ('file4', 'B', 2); 

मैं बनाने के लिए आशा करता हूं उपर्युक्त मानदंडों के आधार पर अगली फ़ाइल को पकड़ने के लिए एक बड़ी ग़लत क्वेरी, जिसके परिणामस्वरूप निम्न क्रम में चार बार चलाया जाना चाहिए:

#1: file1, A, 1 (grab any As first) 
#2: file4, B, 2 (grab any Bs who don't have any Cs with the same client_id) 
#3: file3, C, 1 (grab any Cs) 
#4: file2, B, 1 (same as run #2) 

प्रयास है कि मुझे सब से अधिक दूर मिला प्रत्येक प्रकार के लिए तीन अलग-अलग क्वेरी लिखा था:

--file type 'A' selector 
select * from files where type = 'A' 
--file type 'B' selector 
select * from files where type = 'B' and client_id = (
    select client_id from files group by client_id having count(*) = 1 
); 
--file type 'C' selector 
select * from files where type = 'C' 

मैं पंक्तियों की संख्या प्रत्येक बाद लौटा जाँच करना चाहते हैं और अगर यह 0 उपयोग अगले चयन, लेकिन सभी है एक एसक्यूएल कथन में।

उत्तर

6

आप कुछ नेस्टेड एनालिटिक्स, हालांकि यह थोड़ा और अधिक से अधिक यह शायद चाहिए जटिल लग रहा है इस्तेमाल कर सकते हैं:

select id, type, client_id 
from (
    select t.*, 
    case when type = 'a'then 1 
     when type = 'b' and c_count = 0 then 2 
     when type = 'c' then 3 
    end as rnk 
    from (
    select f.*, 
     sum(case when type = 'a' then 1 else 0 end) 
     over (partition by client_id) as a_count, 
     sum(case when type = 'b' then 1 else 0 end) 
     over (partition by client_id) as b_count, 
     sum(case when type = 'c' then 1 else 0 end) 
     over (partition by client_id) as c_count 
    from files f 
) t 
) 
order by rnk; 

SQL Fiddle दिखा कैसे है कि अंतिम परिणाम के लिए बनाता है।

या हो सकता है थोड़ा बेहतर है, और इस समय केवल एक ही रिकॉर्ड है जो मुझे लगता है कि खींच एक पाश के अंदर अंतिम लक्ष्य है (?):

select id, type, client_id 
from (
    select t.*, 
    dense_rank() over (
     order by case when type = 'a' then 1 
     when type = 'b' and c_count = 0 then 2 
     when type = 'c' then 3 
     end, client_id) as rnk 
    from (
    select f.*, 
     sum(case when type = 'c' then 1 else 0 end) 
     over (partition by client_id) as c_count 
    from files f 
) t 
) 
where rnk = 1; 

Updated SQL Fiddle, दिखा फिर से काम है, तो आप देख सकते हैं मूल्यांकन आदेश वह है जिसे आपने पूछा था।

किसी भी तरह से यह केवल तालिका एक बार मारता है, जो एक फायदा हो सकता है लेकिन पूरी बात, नहीं हो सकता ...

+0

संपादित करने के लिए धन्यवाद, लक्ष्य केवल एक पंक्ति वापस जाने के लिए है जो स्कैन करने के लिए है। तालिका छोटी रहेगी इसलिए पूरी चीज स्कैनिंग एक मुद्दा नहीं है। – cazzer

+0

बस इतना भविष्य में किसी और की मदद करता है - ओरेकल, उनकी सभी चालाकी में मानक के खिलाफ जाने का फैसला किया और डिफ़ॉल्ट बाल्टी को 'अन्यथा' के बजाय 'अन्य' के रूप में तय किया – killjoy

1

यह सभी तर्क वास्तव में कथन द्वारा क्रम में क्रैम किया जा सकता है। यह आपके एसक्यूएल बेवकूफ उदाहरण में काम करता है (यह उपलब्ध कराने के लिए धन्यवाद, यह जवाब इसके बिना एक साथ नहीं आया होगा)। आप बयान द्वारा एक दिलचस्प आदेश के साथ एक चयन * के लिए काफी पूछ रहे हैं। इस आदेश को करने के लिए (आपकी दूसरी हालत, बी जहां सी मौजूद नहीं है) हमें भी स्वयं में शामिल होने की आवश्यकता होगी।

select f.* 
from files f 
left join files a on a.client_id = f.client_id and f.type = 'b' and a.type = 'c' 
order by 
case when f.type = 'a' then 1 
    when f.type = 'b' and a.id is null then 2 
    when f.type = 'c' then 3 
    when f.type = 'b' and a.id is not null then 4 
else 5 end 
संबंधित मुद्दे