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

PostgreSQL, kde je vše v poli

Za předpokladu, že se tabulka spojení řídí osvědčenými postupy a má definovaný jedinečný složený klíč, tj. omezení pro zamezení duplicitních řádků, mělo by fungovat něco jako následující jednoduchý dotaz.

select conversation_id from conversations_users where user_id in (1, 2)
group by conversation_id having count(*) = 2

Je důležité si uvědomit, že číslo 2 na konci je délka seznamu user_id. To se samozřejmě musí změnit, pokud seznam user_id změní délku. Pokud nemůžete předpokládat, že vaše tabulka spojení neobsahuje duplikáty, změňte "count(*)" na "count(distinct user_id)" s určitými možnými náklady na výkon.

Tento dotaz najde všechny konverzace, které zahrnují všechny zadané uživatele, i když konverzace také zahrnuje další uživatele.

Pokud chcete pouze konverzace s přesně pro specifikovanou množinu uživatelů je jedním přístupem použití vnořeného poddotazu v klauzuli where, jak je uvedeno níže. Všimněte si, že první a poslední řádek jsou stejné jako původní dotaz, pouze dva prostřední řádky jsou nové.

select conversation_id from conversations_users where user_id in (1, 2)
   and conversation_id not in
   (select conversation_id from conversations_users where user_id not in (1,2))
group by conversation_id having count(*) = 2

Ekvivalentně můžete použít operátor množiny rozdílu, pokud jej vaše databáze podporuje. Zde je příklad v syntaxi Oracle. (Pro Postgres nebo DB2 změňte klíčové slovo "minus" na "mimo.)

select conversation_id from conversations_users where user_id in (1, 2)
  group by conversation_id having count(*) = 2
minus
  select conversation_id from conversations_users where user_id not in (1,2)

Dobrý optimalizátor dotazů by měl zacházejte s posledními dvěma variantami stejně, ale pro jistotu si to ověřte ve své konkrétní databázi. Například plán dotazů Oracle 11GR2 třídí dvě sady ID konverzace před použitím operátoru minus, ale přeskočí krok řazení pro poslední dotaz. Každý plán dotazů by tedy mohl být rychlejší v závislosti na mnoha faktorech, jako je počet řádků, jader, mezipaměť, indexy atd.



  1. Jak najít závislosti cizího klíče na SQL Server?

  2. Řešení problémů s replikací z databázových klastrů bez GTID do GTID MariaDB

  3. Podporuje váš ovladač ODBC zdroje uživatelských dat?

  4. Definujte proměnnou v rámci select a použijte ji ve stejném výběru