PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

PostgreSQL където всичко е в масив

Ако приемем, че таблицата за свързване следва добра практика и има дефиниран уникален съставен ключ, т.е. ограничение за предотвратяване на дублиране на редове, тогава трябва да направи нещо като следната проста заявка.

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

Важно е да се отбележи, че числото 2 в края е дължината на списъка с user_ids. Това очевидно трябва да се промени, ако списъкът user_id промени дължината. Ако не можете да приемете, че вашата таблица за присъединяване не съдържа дубликати, променете „count(*)“ на „count(distinct user_id)“ на някаква възможна цена в производителността.

Тази заявка намира всички разговори, които включват всички посочени потребители дори ако разговорът включва и допълнителни потребители.

Ако искате само разговори сточно определения набор от потребители, един от подходите е да се използва вложена подзаявка в клаузата where, както е посочено по-долу. Обърнете внимание, че първият и последният ред са същите като оригиналната заявка, само средните два реда са нови.

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

Еквивалентно, можете да използвате оператор за набор разлика, ако вашата база данни го поддържа. Ето един пример в синтаксиса на Oracle. (За Postgres или DB2 променете ключовата дума „минус“ на „освен.)

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)

Добър оптимизатор на заявки трябва третирайте последните два варианта еднакво, но проверете с вашата конкретна база данни, за да сте сигурни. Например планът за заявка на Oracle 11GR2 сортира двата набора идентификатори на разговори, преди да приложи оператора минус, но пропуска стъпката за сортиране за последната заявка. Така че всеки план за заявка може да бъде по-бърз в зависимост от множество фактори, като например броя на редовете, ядрата, кеша, индексите и т.н.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да накарам моята база данни postgresql да използва съпоставяне без значение за главни букви?

  2. Rails:FATAL - Удостоверяването на партньора не бе успешно за потребител (PG::Error)

  3. Как to_timestamp() работи в PostgreSQL

  4. Heroku pg:pull неуспешно попълване на схемата

  5. 7 съвета за най-добри практики за групово зареждане на PostgreSQL данни