如何检索记录但仅当每个链接的子实体列 '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)
我有名为 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)