MySQL: использование «In» с несколькими подзапросами? - PullRequest
1 голос
/ 22 ноября 2010

Я пытаюсь использовать этот запрос:

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 являются общими для двух подзапросов.

Возможно ли это с одним запросом?

ОБНОВЛЕНИЕ:

Я попытаюсь прояснить вопрос немного лучше.

В результате должны быть возвращены все страницы, для которых заданным фильтрам задано определенное значение, ВКЛЮЧАЯ страницы, которыеиметь дополнительные фильтры, которые не являются частью запроса.Другими словами, я на странице с определенными фильтрами, показываю мне все страницы, на которые я могу перейти отсюда, с такими же фильтрами и одним дополнительным набором фильтров.

Это немногосложно объяснить, но я ищу набор результатов, который включает в себя страницы с другими установленными фильтрами, но НЕ страницы с другим значением для того же идентификатора фильтра.

Итак, в этом примере мы хотим, чтобы все страницыфильтр 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 ]

1 голос
/ 22 ноября 2010

Изолировать запрос, который создает ваш список идентификаторов страниц. Вам нужно закончить одним запросом, который возвращает нужные вам значения. Вы можете сделать это так:

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")
1 голос
/ 22 ноября 2010

Вы должны иметь возможность "объединить" объединение наборов результатов 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
1 голос
/ 22 ноября 2010

Попробуйте

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

по этой ссылке

1 голос
/ 22 ноября 2010
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
...