यदि आपका डिज़ाइन संदर्भात्मक अखंडता को लागू करता है, तो आपको तालिका में शामिल होने की आवश्यकता नहीं है residences
इस उद्देश्य के लिए बिल्कुल। साथ ही एक UNIQUE
मानते हुए या PK
(residence_id, amenity_id)
. पर प्रतिबंध (अन्यथा आपको अलग-अलग प्रश्नों की आवश्यकता है!)
सबसे अच्छी क्वेरी इस बात पर निर्भर करती है कि आपको क्या चाहिए बिल्कुल ।
विंडो फ़ंक्शन का उपयोग करके, आप कर सकते हैं इसे एकल क्वेरी स्तर में भी करें:
SELECT count(*) OVER () AS ct
FROM listed_amenities
WHERE amenity_id IN (48, 49, 50)
GROUP BY residence_id
HAVING count(*) = 3
LIMIT 1;
यह विंडो फ़ंक्शन कुल संख्या को पंक्तियों को एकत्रित किए बिना प्रत्येक पंक्ति में जोड़ देता है। SELECT
. में इवेंट के क्रम पर विचार करें क्वेरी:
तदनुसार, आप सभी योग्यता आईडी (या यहां तक कि पूरी पंक्तियों) को वापस करने के लिए एक समान क्वेरी का उपयोग कर सकते हैं और गणना को प्रत्येक पंक्ति में जोड़ सकते हैं (अनावश्यक रूप से):
SELECT residence_id, count(*) OVER () AS ct
FROM listed_amenities
WHERE amenity_id IN (48, 49, 50)
GROUP BY residence_id
HAVING count(*) = 3;
लेकिन बेहतर तरीके से एक सबक्वेरी का उपयोग करें, जो कि आमतौर पर काफी सस्ता है :
SELECT count(*) AS ct
FROM (
SELECT 1
FROM listed_amenities
WHERE amenity_id IN (48, 49, 50)
GROUP BY residence_id
HAVING count(*) = 3
) sub;
आप कर सकते थे आईडी की एक सरणी लौटाएं (सेट . के विपरीत) ऊपर) एक ही समय में, शायद ही किसी और कीमत के लिए:
SELECT array_agg(residence_id ) AS ids, count(*) AS ct
FROM (
SELECT residence_id
FROM listed_amenities
WHERE amenity_id IN (48, 49, 50)
GROUP BY residence_id
HAVING count(*) = 3
) sub;
कई अन्य प्रकार हैं, आपको अपेक्षित परिणाम स्पष्ट करना होगा। इस तरह:
SELECT count(*) AS ct
FROM listed_amenities l1
JOIN listed_amenities l2 USING (residence_id)
JOIN listed_amenities l3 USING (residence_id)
WHERE l1.amenity_id = 48
AND l2.amenity_id = 49
AND l2.amenity_id = 50;
मूल रूप से यह संबंधपरक विभाजन का मामला है। हमने यहां तकनीकों का एक शस्त्रागार इकट्ठा किया है: