वैसे आप सामान्य तालिका व्यंजक का उपयोग कर सकते हैं कोड दोहराव से बचने के लिए:
with cte_s as (
select id_movie, count(id_movie) as awards
from Award natural join awardwinner
where award_year = 2012
group by id_movie
)
select
sub.id_movie, sub.awards
from cte_s as sub
where sub.awards = (select max(sub2.awards) from cte_s as sub2)
या आप विंडो फ़ंक्शन के साथ ऐसा कुछ कर सकते हैं (अनचाहे, लेकिन मुझे लगता है कि PostgreSQL इसकी अनुमति देता है):
with cte_s as (
select
id_movie,
count(id_movie) as awards,
max(count(id_movie)) over() as max_awards
from Award natural join awardwinner
where award_year = 2012
group by id_movie
)
select id_movie
from cte_s
where max_awards = awards
ऐसा करने का दूसरा तरीका rank() फ़ंक्शन (परीक्षण नहीं किया गया, हो सकता है कि आपको एक के बजाय दो सीटीई का उपयोग करना पड़े):
with cte_s as (
select
id_movie,
count(id_movie) as awards,
rank() over(order by count(id_movie) desc) as rnk
from Award natural join awardwinner
where award_year = 2012
group by id_movie
)
select id_movie
from cte_s
where rnk = 1
अपडेट करें जब मैंने यह उत्तर बनाया है, तो मेरा मुख्य लक्ष्य यह दिखाना था कि कोड दोहराव से बचने के लिए सीटीई का उपयोग कैसे करें। जेनरल में, यदि संभव हो तो क्वेरी में एक से अधिक बार सीटीई का उपयोग करने से बचना बेहतर है - पहली क्वेरी 2 टेबल स्कैन (या इंडेक्स सीक) का उपयोग करती है और दूसरा और तीसरा केवल एक का उपयोग करता है, इसलिए मुझे यह निर्दिष्ट करना चाहिए कि इसके साथ जाना बेहतर है इन प्रश्नों। वैसे भी, @Erwin ने अपने उत्तर में यह परीक्षण किया। बस उनके महान प्रमुख बिंदुओं को जोड़ने के लिए:
- मैं
natural join
के विरुद्ध भी सलाह देता हूं इसकी त्रुटि-प्रवण प्रकृति के कारण। असल में, मेरा मुख्य आरडीबीएमएस एसक्यूएल सर्वर है जो इसका समर्थन नहीं कर रहा है इसलिए मुझेouter/inner join
को स्पष्ट करने के लिए और अधिक उपयोग किया जाता है । - अपने प्रश्नों में हमेशा उपनाम का उपयोग करना अच्छी आदत है, इसलिए आप अजीब परिणाम ।
- यह पूरी तरह से व्यक्तिपरक बात हो सकती है, लेकिन आमतौर पर अगर मैं केवल क्वेरी की मुख्य तालिका से पंक्तियों को फ़िल्टर करने के लिए कुछ तालिका का उपयोग कर रहा हूं (जैसे इस क्वेरी में, हम केवल
awards
प्राप्त करना चाहते हैं। वर्ष 2012 के लिए और केवलawardwinner
. से पंक्तियों को फ़िल्टर करें ), मैंjoin
. का उपयोग नहीं करना पसंद करता/करती हूं , लेकिन उपयोग करेंexists
याin
इसके बजाय, यह मेरे लिए अधिक तार्किक लगता है।
with cte_s as (
select
aw.id_movie,
count(*) as awards,
rank() over(order by count(*) desc) as rnk
from awardwinner as aw
where
exists (
select *
from award as a
where a.id_award = aw.id_award and a.award_year = 2012
)
group by aw.id_movie
)
select id_movie
from cte_s
where rnk = 1