为什么这个n-n关系中的查询什么都不返回?

时间:2017-03-14 21:52:24

标签: sql postgresql join sequelize.js

我正在尝试执行以下查询,但没有任何事情发生。我没有结果。

SELECT * FROM "product" 
LEFT OUTER JOIN (
    "product_filter" 
    INNER JOIN "filter_value" 
    ON "filter_value"."filterValueId" = "product_filter"."filterValueId") 
ON "product"."productId" = "product_filter"."productId" 
WHERE "product"."isAdult" = false 
AND ("filter_value"."filterValueId" = '4' 
AND "filter_value"."filterValueId" = '8');

我知道问题来自filterValueId必须等于4和8.如果我删除其中一个,我得到结果。但我需要两者的结果。 filter_value是n-n关系的关系表。

查询对我来说是正确的,但没有任何结果。 更糟糕的是当我执行LEFT OUTER JOIN查询时,我得到了结果

"product_filter" 
INNER JOIN "filter_value" 
ON "filter_value"."filterValueId" = "product_filter"."filterValueId"

我使用sequelize构建以下关系:

db.product.belongsToMany(
db.filterValue, 
{ 
    through: db.productFilter, 
    as: 'productFilters', 
    foreignKey: 'productId' 
});
db.filterValue.belongsToMany(
db.product, 
{ 
    through: db.productFilter, 
    as: 'productFilters', 
    foreignKey: 'filterValueId' 
});

我多次检查表内容,一切都正确。 我真的不明白为什么这个查询什么都不返回?

2 个答案:

答案 0 :(得分:1)

你似乎明白为什么它什么都不返回。过滤器值不能同时为4和8。

我想你想要这样的东西:

select p.*
from "product" p
where p.ProductId in (select pf.ProductId
                      from product_filter pf 
                      where pf.filterValueId in (4, 8)
                      group by pf.ProductId
                      having count(distinct pf.filterValueId = 2)
                     );

注意:您根本不需要过滤表,因为过滤器值在product_filter中。 (这假设某些类型的过滤不需要它。)

您可能会更快地找到两个exists子查询的使用:

select p.*
from "product" p
where exists (select pf.ProductId
              from product_filter pf 
              where pf.ProductId = p.ProductId and
                    pf.filterValueId = 4
             ) and
      exists (select pf.ProductId
              from product_filter pf 
              where pf.ProductId = p.ProductId and
                    pf.filterValueId = 8
             );

答案 1 :(得分:0)

"filter_value"."filterValueId" = '4' AND "filter_value"."filterValueId" = '8

filterValueId不能同时为4和8。

也许你想要

"filter_value"."filterValueId" = '4' OR "filter_value"."filterValueId" = '8