【发布时间】:2010-07-27 04:46:59
【问题描述】:
如何编写一个 SQL 查询,仅当连接表中的所有关联记录都满足某个条件时才返回记录。
例如,如果 A 有很多 B,我想 SELECT * FROM A WHERE 给定 A 的所有相关 B 都有 B.some_val > 值
我知道这可能是一个非常基本的问题,因此感谢您的帮助。另外,如果它有所作为,我正在使用 postgres。
山姆
【问题讨论】:
标签: sql postgresql join
如何编写一个 SQL 查询,仅当连接表中的所有关联记录都满足某个条件时才返回记录。
例如,如果 A 有很多 B,我想 SELECT * FROM A WHERE 给定 A 的所有相关 B 都有 B.some_val > 值
我知道这可能是一个非常基本的问题,因此感谢您的帮助。另外,如果它有所作为,我正在使用 postgres。
山姆
【问题讨论】:
标签: sql postgresql join
假设不需要关联,使用:
SELECT a.*
FROM A a
WHERE EXISTS(SELECT NULL
FROM B b
HAVING MIN(b.some_val) > a.val)
如果您确实需要相关性:
SELECT a.*
FROM A a
WHERE EXISTS(SELECT NULL
FROM B b
WHERE b.id = a.id
HAVING MIN(b.some_val) > a.val)
EXISTS 基于第一个匹配对布尔值进行评估 - 这比使用 IN 更快,并且 - 与使用 JOIN 不同 - 不会重复行。 SELECT 部分无关紧要 - 您可以将其更改为 EXISTS SELECT 1/0 ...,尽管存在明显的除零错误,但查询仍然可以工作。
EXISTS 中的子查询使用聚合函数 MIN 来获取最小的 B.some_val - 如果该值大于 a.val 值,则 a.val 小于所有 b 值。 WHERE 子句的唯一需要是用于关联 - 聚合函数只能在 HAVING 子句中使用。
【讨论】:
EXISTS SELECT 1/0 ...,尽管存在明显的除零错误,但查询仍然有效。
B.some_val - 如果该值大于 a.val 值,则 a.val 为小于所有 b 值。 WHERE 子句的唯一需要是关联 - 聚合函数只能在 HAVING 子句中使用。
select * from A
where -- at least one record in B is greater than some_val
exists (select null from B
where B.some_val > :value
and A.join_column = B.join_column)
and -- no records in B are not greater than some_val
not exists (select null from B
where B.some_val <= :value
and A.join_column = B.join_column)
【讨论】:
以下应该有效:
SELECT *
FROM a
JOIN b ON a.key = b.key AND a.value > b.value
因为这是一个 inner join 而不是 outer join,所以来自 A 的记录只有在 B 中有满足条件的记录时才会被包括在内。
我不使用 PostGRE,所以我不能保证语法完全正确。
【讨论】:
你想要一个 INNER JOIN:
SELECT
A.*
FROM
A
INNER JOIN B
ON A.identifier = B.identifier
WHERE
B.some_val > value
您需要确保存在从 A 到 B 的外键,或其他一些通用标识符。
【讨论】:
select * from a where a.key = b.a_key where b.value > condition
【讨论】:
以书店和书籍为例。
书店ID, bookID
bookID、价格
我想你想退回所有书的价格都大于 X 的书店。
select *
from Bookstore bs1
where bs1.bookstoreID not exist
(
select bs.bookstoreID
from Bookstore bs, Book b
where bs.bookID= b.bookID
b.price < x; -- your value
)
【讨论】: