2013-07-06 7 views
6

मैंने अतीत में केवल सरल एसक्यूएल स्टेटमेंट का उपयोग किया है, लेकिन अचानक मुझे कुछ और जटिल करना है और मेरी गहराई से बाहर है। किसी भी सहायता की सराहना की जाएगी।जटिल (मेरे लिए) एसक्यूएल स्टेटमेंट

मैं टेबल है:

  • Candidates
  • CandidateLanguages
  • CandidateSkills

प्रत्येक उम्मीदवार 1 से अधिक भाषा और अधिक से अधिक 1 Candidate के लिए कौशल

तो हो सकता है "एफआरडीडी", उनके रिकोर CandidateLanguages में डी एस हो सकता है

FRED - ENGLISH 
FRED - FRENCH 

और CandidateSkills में उनके रिकॉर्ड

FRED - RUNNING 
FRED - JUMPING 

और Candidate "जिम" CandidateLanguages में अपने रिकॉर्ड के लिए

JIM - ENGLISH 

और CandidateSkills में उनके रिकॉर्ड हो सकता है हो सकता है

हो सकता है

मेरी क्वेरी को कई कौशल और भाषाओं से मेल खाने वाले उम्मीदवारों को चुनने की आवश्यकता है।

तो अंग्रेजी में उदाहरण के लिए:

उम्मीदवारों जो चयनित भाषाओं के सभी बोलते हैं और चयनित कौशल के सभी के सभी का चयन करें ...

या दूसरे शब्दों में कहें ....

SELECT ALL candidates WHERE 
(language = 'FRENCH' AND language is 'ENGLISH') AND 
(skill = 'RUNNING' AND skill = 'JUMPING') 
ऊपर दो उम्मीदवारों के

, यह केवल वापस आ जाएगी "फ्रेड"

मैं समझता हूँ कि समस्या यह है कि से कई रिकॉर्ड का चयन करने की कोशिश कर के साथ भाषा और कौशल की मेज और मुझे लगता है कि मिलती आवश्यक हो सकता है लगता है, लेकिन अब मैं खो गया हूँ .......

आप सभी आपके इनपुट के लिए धन्यवाद - यह बहुत सराहना की

+0

आप क्वेरी पीछे की कोशिश की है (आप खाली डेटाबेस बनाने के लिए हो सकता है)? "मुझे उन सभी उम्मीदवारों को दें जो कौशल में से किसी एक को याद कर रहे हैं या किसी एक भाषा को याद कर रहे हैं"? कभी-कभी समस्या को दोबारा करने से अन्य/बेहतर समाधान मिल सकते हैं।यदि आप सही जगहों पर वहां "नहीं" चिपके रहते हैं तो आपको वह डेटा देना चाहिए जो आपको चाहिए, लेकिन "गायब नहीं" भाग "सभी" भाग से SQL क्वेरी के रूप में फ़ॉर्मूलेट करना आसान हो सकता है। –

+0

60 अंक है .. 14 और वह दैनिक सीमा तक पहुंचता है, तो उसे कल के लिए इंतजार करना होगा .. – user1974729

+0

@ user1974729: 6 प्रश्नों में अपवॉट का मतलब है 30 प्रतिनिधि, 60 नहीं। –

उत्तर

4

समस्या आप को हल करते हैं संबंधपरक डिवीजन कहा जाता है।(जो होगा - सामान्य रूप में - सबसे कुशल) इसे हल करने How to filter SQL results in a has-many-through relation

एक ही रास्ता: Divided We Stand: The SQL of Relational Division और इसे हल करने के लिए कुछ तरीके के लिए इस सवाल का:

यह लेख देखें

SELECT ALL c.candidate 
FROM Candidates c 
    JOIN CandidateLanguages lang1 
    ON lang1.candidate = c.candidate 
    AND lang1.language = 'English' 
    JOIN CandidateLanguages lang2 
    ON lang2.candidate = c.candidate 
    AND lang2.language = 'French' 
    JOIN CandidateSkills sk1 
    ON sk1.candidate = candidate 
    AND sk1.skill = 'Running' 
    JOIN CandidateSkills sk2 
    ON sk2.candidate = candidate 
    AND sk2.skill = 'Jumping' ; 

एक और तरीका है, जो आसान लगता है लिखने के लिए, खासकर अगर वहाँ भाषाओं और इसमें शामिल कौशल का एक बहुत कुछ कर रहे हैं, उनमें से प्रत्येक में GROUP BY के साथ दो व्युत्पन्न तालिकाओं का उपयोग करने के लिए है:

+०१२३५१६४१०६
SELECT ALL c.candidate 
FROM Candidates c 
    JOIN 
    (SELECT candidate 
     FROM CandidateLanguages 
     WHERE language IN ('English', 'French') 
     GROUP BY candidate 
     HAVING COUNT(*) = 2      -- the number of languages 
    ) AS lang 
     ON lang.candidate = c.candidate 
    JOIN 
    (SELECT candidate 
     FROM CandidateSkills 
     WHERE skill IN ('Running', 'Jumping') 
     GROUP BY candidate 
     HAVING COUNT(*) = 2      -- the number of skills 
    ) AS sk 
     ON sk.candidate = c.candidate ; 
+3

के साथ किसी भी भाषा बोलने के लिए वापस कर देगा यदि आपके पास 15 भाषाएं और 60 कौशल हैं? – gaborsch

+1

@GaborSch फिर आपके पास 60 + 15 = 75 शामिल हैं। मैं आपको आश्वासन देता हूं कि (ज्यादातर मामलों में) यह 'ग्रुप बाय' प्रश्नों की तुलना में अधिक कुशल होगा। –

+0

आपकी मदद और टिप्पणियों के लिए सभी को धन्यवाद। अत्यन्त सराहनीय। – user2556881

-2

आप का वर्णन कर रहे हैं उम्मीदवारों और कौशल और उम्मीदवारों और भाषाओं के बीच भी कई रिश्तों के लिए कई। उम्मीद है कि आपके डेटाबेस में आवश्यक टेबल हैं। क्वेरी इस सदृश होगा:

select yourfields 
from candidate c join candidateLanguage cl on c.id = cl.candidateId 
join languages l on cl.languageId = l.id 
join candidateSkill cs on c.id = cd.candidateId 
join skill s on s.id = cs.skillId 
where l.language in ('FRENCH', 'ENGLISH') 
and s.skill in ('RUNNING', 'JUMPING') 
+4

वह क्वेरी विवरण के समतुल्य नहीं है, यह किसी भी कौशल को – AD7six

1

यदि आप चाहते हैं सभी कौशल और सभी भाषाओं, बस गुणा गिनती पर्याप्त होगा।

select c.id 
from candidate c 
join candidateLanguage cl on c.id = cl.candidateId 
join language l on cl.languageId = l.id 
join candidateSkill cs on c.id = cd.candidateId 
join skill s on s.id = cs.skillId 
group by c.id 
having count(*) = 4 

having हालत

having count(*) = 
    (select count(*) from skill) * (select count(*) from language) 

मैं यहाँ क्या करते हैं के रूप में व्यक्त किया जा सकता है?

  • लिस्टिंग के लिए सभी संभव उम्मीदवार-भाषा-कौशल तीनो
  • उन्हें उम्मीदवार
  • द्वारा समूहन अगर गिनती इस उम्मीदवार सभी संयोजनों हैं के लिए (कौशल की गिनती) * (भाषाओं के गिनती) तो के बराबर वर्तमान

संपादित करें:

आप केवल उन्हीं भाषाओं और कौशल के एक सबसेट चाहते हैं, आप इसे फ़िल्टर कर सकते हैं:

select c.id 
from candidate c 
join candidateLanguage cl on c.id = cl.candidateId 
join language l on cl.languageId = l.id 
join candidateSkill cs on c.id = cd.candidateId 
join skill s on s.id = cs.skillId 
where l.name in ('English', 'French') 
    and s.name in ('RUNNING', 'JUMPING') 
group by c.id 
having count(*) = 4 

यहाँ अंतर यह है कि आप केवल उन कौशल और भाषाओं कि आपके मापदंड से मेल खाने रहे हैं भरोसा कर सकते हैं है।

0

सुरुचिपूर्ण, लेकिन कुशल नहीं है।

SELECT 
    * 
FROM 
    Candidates c 
WHERE 
    (SELECT COUNT(*) 
    FROM CandidateLanguages cl 
    WHERE cl.candidateId = c.candidateId AND cl.language in ('FRENCH', 'ENGLISH') 
) = 2 
    AND 
    (SELECT COUNT(*) 
    FROM CandidateSkills cs 
    WHERE cs.candidateId = c.candidateId AND cs.skill in ('RUNNING', 'JUMPING') 
) = 2 
0

यदि आपका डेटा क्वेरी के रूप में "मुझे सभी उम्मीदवारों को सभी ज्ञात कौशल है कि हम एक तालिका में सूचीबद्ध किया है कि, और सभी ज्ञात भाषाओं हम एक अलग तालिका में सूचीबद्ध है दो" लिखा जा सकता है, और न सिर्फ , तो आप इन डेटा के आधार पर प्रश्नों में से एक का उपयोग कर सकते "अंग्रेजी और फ्रेंच, और दोनों कूद और चलाने के साथ सभी उम्मीदवारों":

select 
    * 
from 
    Candidates as C 
where 
    (select count(*) from CandidateLanguages where CandidateName = C.Name) = (select count(*) from Languages) 
and (select count(*) from CandidateSkills where CandidateName = C.Name) = (select count(*) from Skills) 
go 

select 
    * 
from 
    Candidates 
where 
    Name not in (
     select 
      C.Name 
     from 
      (Candidates as C cross join Languages as L) 
      left join CandidateLanguages as CL on C.Name = CL.CandidateName and L.Name = CL.LanguageName 
     where 
      CL.CandidateName is null 
    ) 
and Name not in (
     select 
      C.Name 
     from 
      (Candidates as C cross join Skills as S) 
      left join CandidateSkills as CS on C.Name = CS.CandidateName and S.Name = CS.LanguageName 
     where 
      CS.CandidateName is null 
    ) 
go 

पूर्ण उदाहरण कोड है कि LINQPad में परीक्षण किया जा सकता available here है।

-1
select candidate-name,resulttblskills1.sumCOLRATIOSKILLS,resulttbllanguages1.sumCOLRATIOLanguages from candidates candidates1 

    join (select count(*) as sumCOLRATIOskills 
      from candidateskills skills1 
      where skills1.requiredskills in ('jumping','canoeing','mostlygoofing' 
      group by id 
     ) as resulttblskills1 on resulttblskills1.id = candidates1.id 

    join (select count(*) as sumCOLRATIOLANGUAGES 
      from candidatelanguages languages1  
      where languages1.requiredlanguages in ('French','english','esparanto') 
      group by id) as resulttbllanguages1 on resulttbllanguages1.id = candidates1.id 

    where resulttblskills1.sumCOLRATIOSKILLS > 1 
      and resulttbllanguages1.sumCOLRATIOLANGUAGES > 1 
+0

क्या आपके पास 'resulttblskills1' और' resulttblskills2' पर 'id' कॉलम है? – Camouflage

+0

या आप प्रत्येक आईडी के लिए योग प्राप्त करने और प्राथमिक कुंजी पर समेकित तालिका में शामिल होने के लिए आईडी द्वारा समूहबद्ध कर रहे हैं .. – user1974729

+1

मैं इसे चुनिंदा रेखा पर नहीं देख सकता, शायद आप इसे वहां जोड़ना भूल गए हैं। इसके अलावा मुझे लगता है कि आप 'sumCOLRATIOSKILLS> 1' स्थिति को भी सही करना चाहते हैं। – Camouflage

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