如何检索记录但仅当每个链接的子实体列 'archived' 设置为 true 时?

How retrieve a record but only when every linked sub entities column 'archived' is set to true?

我有名为 Record 的实体存储在 postgresql table。

这些记录可以在备份媒体上存档。

关联是这样的:Record <-> AssocationTable <-> Media

一条记录可以与多个媒体相关联。关联 table 提供一个属性:archived as boolean

我想写一个 return 记录列表的查询。 但是我只想在每个与媒体的关联都将 archived 属性设置为 true 时找到一条记录。

样本:

媒体(id,名称)
1、第一媒体
2、第二媒体

记录(id,姓名)
10、第一条记录
20、第二条记录
30、第三条记录

关联(媒体 ID、记录 ID、已存档)
1, 10, 真
2、10、错误
1、20、假
1、30,真
2、30,真

所以,这里我们有 3 条记录,记录 10 链接到媒体 1 和 2,但媒体 2 未存档,所以我不想要它。记录 20 仅链接到媒体 1 但未存档,同样我不想要它。然后记录 30 链接到媒体 1 和 2,并且都标记为已存档。这就是我想要找到的那种记录。

我试过类似的东西:

SELECT r FROM Record r, ArchiveMediasRecords ass, AchiveMedia a WHERE ass MEMBER OF r.medias AND ass MEMBER OF a.records AND ass.archived = true

但是 ass.archived=true 不是匹配 'every' 关联的标准。

谢谢。

注:Java8u51、Eclipselink 2.6 和 PostgreSQL9.4

编辑,使用纯 SQL 给我这个:

EXPLAIN SELECT * FROM recorder.records r WHERE true = ALL (
    SELECT archived FROM recorder.archive_medias_records WHERE record_id = r.id
)


Seq Scan on records r  (cost=0.00..6026.82 rows=190 width=182)
  Filter: (SubPlan 1)
  SubPlan 1
    ->  Seq Scan on archive_medias_records  (cost=0.00..31.63 rows=9 width=1)
          Filter: (record_id = r.id)

真实数据:

记录
2001 年;.....
2002;.....
2003 年;.....

媒体
1;"PLop";....
5;"plip";....

协会
1;2001;真实

1;2002;TRUE  
5;2002;FALSE  

1;2003;TRUE  
5;2003;TRUE  

预期: 记录 2001 年和 2003 年

可能有几种方法可以做到这一点,但我会尝试将 "ALL" 与子查询一起使用: http://docs.oracle.com/html/E13946_04/ejb3_langref.html#ejb3_langref_all_any

"Select r FROM Record r where true = ALL (Select amr.archived from  ArchiveMediasRecord amr where amr.record = r)"

以上查询假定您有 ArchiveMediasRecord.record 关系。如果不这样做,则需要像在原始查询中那样使用 member of。

DDL 和示例数据:

CREATE TABLE media (
  id SERIAL PRIMARY KEY,
  name TEXT
);
INSERT INTO media VALUES
  (1,'PLop'),
  (5,'plip');

CREATE TABLE record (
  id SERIAL PRIMARY KEY,
  name TEXT
);
INSERT INTO record VALUES
  (2001,'First record'),
  (2002,'Second record'),
  (2003,'Third record');

CREATE TABLE assosiation(
  mediaid INTEGER REFERENCES media(id),
  recordid INTEGER REFERENCES record(id),
  archived BOOLEAN
);
INSERT INTO assosiation VALUES
  (1,2001,true),
  (1,2002,true),
  (5,2002,false),
  (1,2003,true),
  (5,2003,true);

psql 低于 returns 预期值:

SELECT * FROM record r WHERE
true = ALL (
  SELECT archived FROM assosiation WHERE recordid = r.id
);

输出:

  id  |     name     
------+--------------
 2001 | First record
 2003 | Third record
(2 rows)