sql - 选择多对多关系中的所有子集

标签 sql ruby-on-rails postgresql

在我正在构建的 Rails 3 应用程序中,我有这三个类:

class Instrument < ActiveRecord::Base
  has_many :parts
  has_many :pieces, through: :parts
end    
class Part < ActiveRecord::Base
  belongs_to :instrument
  belongs_to :piece
end
class Piece < ActiveRecord::Base
  has_many :parts
  has_many :instruments, through: :parts
end

我正在寻找一种方法来选择所有 Pieces,其中关联的乐器是任意一组乐器的子集。

为了避免混淆我举个例子:given

  • Piece(id:1) 与乐器:[1,2,3],
  • Piece(id:2) 与 [1,2,3,4]
  • [1,3,4] 的片段 (id:3)
  • Piece(id:4) 与 [2],

somequery(1,2,3,4) 应该产生所有四个部分,somequery(1,2,3) 只产生 1 和 4,somequery (1,3,4) 仅第 3 部分,somequery(2) 仅第 4 部分。

我正在使用 rails 3.2,rails 中的解决方案会很棒,但 sql 也很好,最好是 postgres,但如果有针对此问题的特定于 mysql 的解决方案,那也很好。此外,我没有使用一个相对较小的数据库(1000 多件,50 件仪器和 15.000 个零件),它没有被大量查询,所以如果查询效率不是最佳的,那也没问题。

作为最后的免责声明,我对 ruby​​/rails 了如指掌,但对 SQL 还是相当陌生。

感谢您的帮助!

最佳答案

DROP SCHEMA tmp CASCADE;
CREATE SCHEMA tmp;

SET search_path='tmp';


CREATE TABLE instrument
        ( id INTEGER NOT NULL PRIMARY KEY
        , zname varchar
        );
INSERT INTO instrument(id, zname) VALUES
(1, 'instrument_1'), (2, 'instrument_2')
, (3, 'instrument_3'), (4, 'instrument_4');

CREATE TABLE piece
        ( id INTEGER NOT NULL PRIMARY KEY
        , zname varchar
        );
INSERT INTO piece(id, zname) VALUES
(1, 'piece_1'), (2, 'piece_2'), (3, 'piece_3'), (4, 'piece_4');

CREATE TABLE has_part
        ( piece_id INTEGER NOT NULL
        , instrument_id INTEGER NOT NULL
        , PRIMARY KEY (piece_id,instrument_id)
        );

INSERT INTO has_part(piece_id,instrument_id) VALUES
(1,1), (1,2), (1,3)
, (2,1), (2,2), (2,3), (2,4)
, (3,1), (3,3), (3,4)
, (4,2)
        ;

纯sql(不是双重否定NOT EXISTS , NOT IN():

SELECT zname
FROM piece pp
WHERE NOT EXISTS (
        SELECT * FROM has_part nx
        WHERE nx.piece_id = pp.id
        AND nx.instrument_id NOT IN (1,2,3)
        )
        ;

关于sql - 选择多对多关系中的所有子集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11117622/

相关文章:

java - 我们如何使用 java 将复杂的 NativeQuery 结果映射到 DTO 对象

sql - nvarchar 是否总是占用 varchar 两倍的空间?

mysql - 从特定数据库中检索所有表名、列名和列值

ruby-on-rails - 你如何知道 Rails 应用程序中的 Rails 版本?

ruby-on-rails - Heroku 迁移 : type modifier is not allowed for type "bytea"

ruby-on-rails - rspec 不保存到数据库

postgresql - 使用 Join 和聚合函数时合并两个表中的两列

sql - 删除单个用户除最早的 20 行以外的所有行

sql - 具有不同组合的产品和产品包的数据库模型

sql - 如何将 UPDATE CASCADE 添加到 Rails-Postgres 迁移中?