MySQL:在多个子查询中使用“In”?

时间:2010-11-22 04:04:31

标签: sql mysql subquery in-subquery

我正在尝试使用此查询:

SELECT COUNT(PF.PageID) AS Total,P.PageID
FROM Pages P
LEFT JOIN Pages_Filters PF ON PF.PageID=P.PageID
WHERE P.PageID IN (
    (SELECT PageID
       FROM Pages_Filters
       WHERE FilterID="1"
       AND FilterOptionID="2"
    ),
    (SELECT PageID
       FROM Pages_Filters
       WHERE FilterID="7"
       AND FilterOptionID="57"
    )
)
AND P.PageID !="283"
GROUP BY PF.PageID

产生错误:

Sub-query returns more than 1 row

我希望MySQL合并所有子查询的结果,并使用共同的值作为主查询中的IN子句。

因此,如果第一个子查询返回1,2,4而第二个子查询返回2,3,4,则“in”子句将显示为:

WHERE P.PageID IN (2,4)

因为2和4是两个子查询共有的值。

这可以用一个查询吗?

更新:

我将尝试更好地澄清这个问题。

结果应该返回将指定过滤器设置为特定值的所有页面INCLUDING设置了不属于查询的额外过滤器的页面。换句话说,我在一个包含某些过滤器的页面上,向我展示了我可以从这里找到的具有相同过滤器的所有页面,并且还有一个额外的过滤器集。

解释起来有点棘手,但我正在寻找一个结果集,其中包含设置了其他过滤器的页面,但不是具有相同过滤器ID的不同值的页面。

因此,在示例中,我们希望所有将过滤器1设置为值2的页面,并将过滤器7设置为57.我们还希望分配具有其他过滤器(除1和7之外)的页面,但不要求具有过滤器7的页面设置为57以外的值,而不是将过滤器1设置为2以外的值的页面。

使用示例数据更新

Pages_Filters:

PageID  FilterID    FilterOptionID
297        2           5
297        7           57
297        9           141
305        2           5
101        2           5
101        7           57

页数:

PageID   PageName
297        Some Page
305        Another Page
101        A Stupid Page

在这种情况下,我应该可以问:“过滤器2设置为5的哪些页面,过滤器7设置为57,过滤器9设置为141”?

答案应该是“只有297”。

4 个答案:

答案 0 :(得分:1)

SELECT COUNT(PF.PageID) AS Total,P.PageID
FROM Pages P
LEFT JOIN Pages_Filters PF ON PF.PageID=P.PageID
WHERE (PF.FilterID="1"
       AND PF.FilterOptionID="2")
    OR (PF.FilterID="7"
       AND PF.FilterOptionID="57" )
AND P.PageID !="283"
GROUP BY PF.PageID

在思考并阅读了Insane的评论后,我意识到这可能是你想要的。基本上我创建的派生表创建了上面两个查询的交集。

SELECT COUNT(PF.PageID) AS Total,P.PageID
FROM Pages P
LEFT JOIN (Select PF1.* from Pages_Filters PF1 
           INNER JOIN Page_Filters PF2 ON PF1.PageID = PF2.Page_ID
           WHERE PF1.FilterID = "1" AND PF2.FilterOptionID = "2"
             AND PF2.FilterID = "7" AND PF2.FilterOptionID = "57"
) PF ON PF.PageID=P.PageID
WHERE P.PageID !="283"
GROUP BY PF.PageID

答案 1 :(得分:1)

您应该能够“合并”结果集union UNION/UNION ALL

这样的东西
SELECT COUNT(PF.PageID) AS Total,P.PageID
FROM Pages P
LEFT JOIN Pages_Filters PF ON PF.PageID=P.PageID
WHERE P.PageID IN (
    SELECT PageID
       FROM Pages_Filters
       WHERE FilterID="1"
       AND FilterOptionID="2"
    UNION ALL
    SELECT PageID
       FROM Pages_Filters
       WHERE FilterID="7"
       AND FilterOptionID="57"
)
AND P.PageID !="283"
GROUP BY PF.PageID

答案 2 :(得分:1)

试试这个

SELECT COUNT(PF.PageID) AS Total,P.PageID
FROM Pages P
LEFT JOIN Pages_Filters PF ON PF.PageID=P.PageID
WHERE P.PageID IN (
    SELECT GROUP_CONCAT(DISTINCT(PageID))
    FROM Pages_Filters
    WHERE (FilterID="1" AND FilterOptionID="2")
    AND (FilterID="7" AND FilterOptionID="57")
)
AND P.PageID !="283"
GROUP BY PF.PageID

或者您可以尝试类似

的内容

http://dev.mysql.com/doc/refman/5.0/en/exists-and-not-exists-subqueries.html

来自此链接

答案 3 :(得分:1)

隔离产生您的PageID列表的查询。您需要最终得到一个返回所需值的查询。你可以这样做:

SELECT PageID P1 FROM Page_Filters
WHERE  FilterID = "1" AND FilterOptionID = "2" AND EXISTS
    (SELECT * FROM PageID P2 
    WHERE P2.PageID = P1.PageID AND FilterID = "7" AND FilterOptionID = "57")