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

truy vấn cho một tập hợp trong cơ sở dữ liệu quan hệ

Tôi sẽ không bình luận về việc liệu có một lược đồ phù hợp hơn để thực hiện việc này hay không (hoàn toàn có thể xảy ra), nhưng đối với một lược đồ có các cột nameitem , truy vấn sau sẽ hoạt động. (cú pháp mysql)

SELECT k.name
FROM (SELECT DISTINCT name FROM sets) AS k
INNER JOIN sets i1 ON (k.name = i1.name AND i1.item = 1)
INNER JOIN sets i2 ON (k.name = i2.name AND i2.item = 3)
INNER JOIN sets i3 ON (k.name = i3.name AND i3.item = 5)
LEFT JOIN sets ix ON (k.name = ix.name AND ix.item NOT IN (1, 3, 5))
WHERE ix.name IS NULL;

Ý tưởng là chúng ta có tất cả các khóa đã đặt trong k , sau đó chúng tôi kết hợp với dữ liệu mục đã đặt trong sets một lần cho mỗi mục đã đặt trong bộ mà chúng tôi đang tìm kiếm, ba trong trường hợp này. Mỗi một trong ba liên kết bên trong với bí danh bảng i1 , i2i3 lọc ra tất cả các tên đã đặt không chứa mục được tìm kiếm với phép nối đó. Cuối cùng, chúng ta có một phép nối bên trái với sets với bí danh bảng ix , mang lại tất cả các mục bổ sung trong bộ, tức là mọi mục mà chúng tôi không tìm kiếm. ix.nameNULL trong trường hợp không tìm thấy các mục bổ sung, đó là chính xác những gì chúng tôi muốn, do đó, WHERE mệnh đề. Truy vấn trả về một hàng chứa khóa tập hợp nếu tập hợp được tìm thấy, không có hàng nào khác.

Chỉnh sửa: Ý tưởng đằng sau câu trả lời của sập có vẻ tốt hơn nhiều so với của tôi, vì vậy, đây là phiên bản ngắn hơn một chút cùng với lời giải thích.

SELECT sets.name
FROM sets
LEFT JOIN (
    SELECT DISTINCT name
    FROM sets
    WHERE item NOT IN (1, 3, 5)
) s1
ON (sets.name = s1.name)
WHERE s1.name IS NULL
GROUP BY sets.name
HAVING COUNT(sets.item) = 3;

Ý tưởng ở đây là truy vấn con s1 chọn các khóa của tất cả các bộ có chứa các mục khác mà chúng tôi đang tìm kiếm. Do đó, khi chúng ta rời khỏi tham gia sets với s1 , s1.nameNULL khi tập hợp chỉ chứa các mục mà chúng tôi đang tìm kiếm. Sau đó, chúng tôi nhóm theo khóa thiết lập và lọc ra bất kỳ nhóm nào có số lượng mục không chính xác. Sau đó, chúng tôi chỉ còn lại những bộ chỉ chứa các mục chúng tôi đang tìm kiếm và có độ dài chính xác. Vì các bộ chỉ có thể chứa một mục một lần, nên chỉ có thể có một bộ đáp ứng tiêu chí đó và đó là bộ chúng tôi đang tìm kiếm.

Chỉnh sửa: Nó chỉ cho tôi biết cách thực hiện điều này mà không cần loại trừ.

SELECT totals.name
FROM (
    SELECT name, COUNT(*) count
    FROM sets
    GROUP BY name
) totals
INNER JOIN (
    SELECT name, COUNT(*) count
    FROM sets
    WHERE item IN (1, 3, 5)
    GROUP BY name
) matches
ON (totals.name = matches.name)
WHERE totals.count = 3 AND matches.count = 3;

Truy vấn con đầu tiên tìm tổng số các mục trong mỗi tập hợp và truy vấn thứ hai tìm ra tổng số các mục phù hợp trong mỗi tập hợp. Khi matches.count là 3, tập hợp có tất cả các mục mà chúng tôi đang tìm kiếm và nếu totals.count cũng là 3, bộ không có thêm bất kỳ mục nào.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cách chuyển đổi kiểu cột varchar thành kiểu ngày tháng mà không làm mất ngày tháng

  2. mysql tìm nạp tổng php

  3. SQL / MySQL - Thứ tự theo độ dài của cột

  4. Làm thế nào để kéo tất cả id sản phẩm, giao diện, tên sản phẩm, mô tả trong magento chỉ bằng cách sử dụng mysql?

  5. Cách đơn giản nhất để lưu trữ dữ liệu từ chương trình java sang MySQL là gì?