sql >> Databáze >  >> RDS >> PostgreSQL

Získejte počet řádků po GROUP BY

Pokud váš návrh vynucuje referenční integritu, nemusíte se připojovat k tabulce residences pro tento účel vůbec. Také za předpokladu UNIQUE nebo PK omezení na (residence_id, amenity_id) (jinak potřebujete jiné dotazy!)

Nejlepší dotaz závisí na tom, co přesně potřebujete .

Pomocí funkce okna můžete dokonce to udělat na úrovni jediného dotazu:

SELECT count(*) OVER () AS ct
FROM   listed_amenities
WHERE  amenity_id IN (48, 49, 50)
GROUP  BY residence_id
HAVING count(*) = 3
LIMIT  1;

Tato funkce okna připojí celkový počet ke každému řádku bez agregace řádků. Zvažte sled událostí v SELECT dotaz:

V souladu s tím můžete použít podobný dotaz k vrácení všech způsobilých ID (nebo dokonce celých řádků) a připojit počet ke každému řádku (redundantně):

SELECT residence_id, count(*) OVER () AS ct
FROM   listed_amenities
WHERE  amenity_id IN (48, 49, 50)
GROUP  BY residence_id
HAVING count(*) = 3;

Ale raději použijte poddotaz, ten je obvykle mnohem levnější :

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;

Mohli byste vrátí pole ID (na rozdíl od set výše) ve stejnou dobu za téměř žádné další náklady:

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;

Existuje mnoho dalších variant, museli byste si ujasnit očekávaný výsledek. Jako tento:

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;

V podstatě je to případ relačního rozdělení. Zde jsme shromáždili arzenál technik:




  1. B-strom vs hash tabulka

  2. Instalace Ubuntu 18.04 pro SQL Server 2019 na virtuálním počítači pomocí VMware Workstation

  3. Oracle - rozdělení jednoho řádku na více řádků

  4. MySQL:jak zabránit vložení řádku se všemi sloupci =NULL?