Has-Many-Through:如何选择没有关系的记录或关系中的某些条件?

时间:2015-06-09 04:49:47

标签: postgresql

有三个表:businessescategoriescategorizations

CREATE TABLE businesses (
  id SERIAL PRIMARY KEY,
  name varchar(40)
);

CREATE TABLE categories (
  id SERIAL PRIMARY KEY,
  name varchar(40)
);

CREATE TABLE categorizations (
  business_id integer,
  category_id integer
);

所以business有很多categoriescategorizations

如果我想选择没有类别的企业,我会做点什么 像这样:

SELECT businesses.* FROM businesses
LEFT OUTER JOIN categorizations
ON categorizations.business_id = businesses.id
LEFT OUTER JOIN categories
ON categories.id = categorizations.category_id
GROUP BY businesses.id
HAVING count(categories.id) = 0;

问题是:如何选择没有类别AND的企业 名为" Media"在一个查询?

3 个答案:

答案 0 :(得分:2)

您可以使用联合:

SELECT businesses.* 
FROM businesses
LEFT OUTER JOIN categorizations
ON categorizations.business_id = businesses.id
GROUP BY businesses.id
HAVING count(categorizations.business_id) = 0

UNION 

SELECT businesses.* 
FROM businesses
INNER JOIN categorizations
ON categorizations.business_id = businesses.id
INNER JOIN categories
ON categories.id = categorizations.category_id
WHERE categories.name = 'Media';

请注意,在第一个实例(根本没有类别的企业)中,您不需要加入类别 - 您可以检测联结表中缺少类别。如果同一个商家可能多次拥有相同的类别,则需要使用DISTINCT引入第二个查询。

答案 1 :(得分:2)

我会尝试:

SELECT b.* FROM businesses b
    LEFT JOIN categorizations cz ON b.business_id = cz.business_id
    LEFT JOIN categories cs ON cz.category_id = cs.category_id
    WHERE COALESCE(cs.name, 'Media') = 'Media';

...希望没有businesses的{​​{1}}在其连接上获得NULL条目。

答案 2 :(得分:0)

双重否定技巧适用于这种选择:

SELECT * FROM businesses b
WHERE NOT EXISTS (
    SELECT *
    FROM categorizations bc
    JOIN categories c ON bc.category_id = c.category_id
    WHERE bc.business_id = b.business_id
    AND c.name <> 'Media'
    );