PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Cách tìm các mục có * tất cả * các danh mục phù hợp

ActiveRecord

Đối với ActiveRecord, bạn có thể đặt một phương thức như thế này trong lớp Item của mình:

def self.with_all_categories(category_ids)
  select(:id).distinct.
    joins(:categories).
    where('categories.id' => category_ids).
    group(:id).
    having('count(categories.id) = ?', category_ids.length)
end

Sau đó, bạn có thể lọc các truy vấn của mình như sau:

category_ids = [1,2,3]
Item.where(id: Item.with_all_categories(category_ids))

Bạn cũng có thể sử dụng phạm vi để làm cho nó thân thiện hơn một chút:

class Item
  scope :with_all_categories, ->(category_ids) { where(id: Item.ids_with_all_categories(category_ids)) }

  def self.ids_with_all_categories(category_ids)
    select(:id).distinct.
      joins(:categories).
      where('categories.id' => category_ids).
      group(:id).
      having('count(categories.id) = ?', category_ids.length)
  end
end

Item.with_all_categories([1,2,3])

Cả hai sẽ tạo ra SQL này

SELECT "items".*
FROM "items"
WHERE "items"."id" IN
  (SELECT DISTINCT "items"."id"
   FROM "items"
   INNER JOIN "categories_items" ON "categories_items"."item_id" = "items"."id"
   INNER JOIN "categories" ON "categories"."id" = "categories_items"."category_id"
   WHERE "categories"."id" IN (1, 2, 3)
   GROUP BY "items"."id" 
   HAVING count(categories.id) = 3)

Về mặt kỹ thuật, bạn không cần distinct một phần của truy vấn con đó, nhưng tôi không chắc liệu có hay không sẽ tốt hơn cho hiệu suất.

SQL

Có một vài cách tiếp cận trong SQL thô

SELECT *
FROM items
WHERE items.id IN (
  SELECT item_id
  FROM categories_items
  WHERE category_id IN (1,2,3)
  GROUP BY item_id
  HAVING COUNT(category_id) = 3
)

Điều đó sẽ hoạt động trong SQL Server - cú pháp có thể hơi khác trong Postgres. Hoặc

SELECT *
FROM items
WHERE items.id IN (SELECT item_id FROM categories_items WHERE category_id = 1)
  AND items.id IN (SELECT item_id FROM categories_items WHERE category_id = 2)
  AND items.id IN (SELECT item_id FROM categories_items WHERE category_id = 3)


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Làm thế nào để một Hàm được lưu trữ Postgres có thể trả về một bảng

  2. Cập nhật đơn đặt hàng trả lại bằng postgresql

  3. Làm cách nào để thêm khóa chính tự động tăng dần vào bảng hiện có, trong PostgreSQL?

  4. Làm cách nào để liên kết bảng tính Google với PostgreSQL?

  5. Chỉ mục đa cột trên 3 trường có kiểu dữ liệu không đồng nhất