2012-03-30 5 views
3

Здесь может быть легко решение, но похоже, что я сработал. Я пытаюсь запросить таблицу на основе массива значений в двух столбцах. Здесь уместна структура таблицы и примеры данныеMYSQL Select Statement with IN clause и несколько условий

comment table 
id, userId, articleId .... etc etc 

article table 
id, userId .... etc etc 

Data: UserIds = 3, 10. ArticleIds = 1, 2 

Скажем, я пытаюсь найти все комментарии для конкретного набора идентификаторов статей: 1,2

Я могу легко использовать этот запрос

select * from comments WHERE articleId IN(1,2) 

Однако здесь он становится сложным. У меня есть запрос, который выполняется перед запросом комментариев, который определяет соответствующие идентификаторы статьи. Эти идентификаторы находятся в массиве. Также в массиве находятся соответствующие идентификаторы пользователей для каждой статьи.

Теперь я хочу выполнить запрос таблицы комментариев только для статей в массиве (1,2) И только для комментариев, сделанных автором (3, 10).

Простой запрос, приведенный выше, вернет все комментарии к статьям 1 и 20. Так, например, я не могу понять, где добавить еще одно условие, в котором говорится о комментариях onyl для статьи 1, 20 И соответствующих userId, 3, 10 .

Любая помощь или предложения были бы высоко оценены!

+0

I ваш массив из PHP массив или массив MySql? – Diego

+0

Я думаю, что предложение HAVING могло бы помочь вам здесь http://dev.mysql.com/doc/refman/5.5/en/select.html – martynthewolf

+0

, может быть, это не изящный способ, но одним из решений было бы значения с использованием разделителя. что если вы хотите статьи 1 и автора 3 или статьи 2 и автора 10 (а не статьи 1 и автора 10) .. означает 'CONCAT (userId, '_', articleId) IN ('1_3', '2_10')'. – mishu

ответ

1

Я думаю, что самый простой способ, чтобы написать:

SELECT comments.* 
    FROM articles 
    JOIN comments 
    ON articles.id = comments.articleId 
    AND articles.userId = comments.userId 
WHERE articles.id IN (1, 2) 
; 

Предложение AND articles.userId = comments.userId является то, что навязывает ваш «только для тех замечаний, сделанных автором оригинального "требование.

В качестве альтернативы, вы можете использовать EXISTS пункт:

SELECT * 
    FROM comments 
WHERE articleId IN (1, 2) 
    AND EXISTS 
     (SELECT 1 
      FROM articles 
      WHERE id = comments.articleId 
      AND userId = comments.userId 
     ) 
; 

или однорядные подзапрос:

SELECT * 
    FROM comments 
WHERE articleId IN (1, 2) 
    AND userId = 
     (SELECT userId 
      FROM articles 
      WHERE id = comments.articleId 
     ) 
; 
+0

Ваше первое предложение работает точно так, как я этого хотел. Я выполняю некоторые тесты, чтобы убедиться, но я выполнил несколько различных комбинаций, и все они возвращают соответствующие данные. Я очень ценю быстрый ответ. Я собираюсь запустить еще пару тестов, тогда я помету ваш ответ как правильный. Быстрый вопрос ... являются ли какие-либо из двух других запросов, которые вы указали выше, более или менее эффективными? В очередной раз благодарим за помощь! –

+0

@K_C: Единственный способ окончательно решить вопрос производительности - попробовать в обоих направлениях - все эти запросы возвращают одинаковые результаты, поэтому они заменяют замену, и вы можете напрямую сравнивать их, но я бы поставил что метод 'JOIN' является самым быстрым. Из того, что я читал, MySQL не очень хорошо оптимизирует коррелированные подзапросы ('(SELECT ...)' подвыражения, которые относятся к полям во внешнем запросе), которые требуются обоим последним запросам. – ruakh

+0

Спасибо! Я тоже попробую других, но ваш первый идеальный! Отметьте это как ответ. Еще раз спасибо вам (и всем остальным) за невероятные быстрые ответы! –

0

Вы можете добавить столько IN заявления, как вы хотите:

select * from comments WHERE articleId IN(1,2) AND userId IN (3,10) 
+0

это лучшее решение –

+0

@gavincattell - Я думал, что ваше решение будет работать, но я думаю, что я не был ясно в своем посте. Я ищу только комментарии автораId = 3 для articleId = 1. Или authorId = 10 и articleId = 2. Я очень ценю быстрый ответ! –

0

Разве вы не можете просто сделать запрос, который запускает первый вложенный запрос в пределах вашего указанного запроса:

SELECT * FROM `comments` WHERE `articleId` IN(1,2) AND `userId` IN (__subquery__) 
1

Вы пробовали только

select * from comments WHERE articleId IN(1,2) and authorId in (3,10) 

Если нет, уточните пожалуйста, почему это так.

+0

Это не удовлетворяет требованию «только для комментариев, сделанных оригинальным автором»: оно вернет все комментарии * либо * пользователя к * любой * статье, а не только возвращает комментарии, сделанные каждым пользователем к его/ее * собственный * статья. – ruakh

+0

Хорошо, пожалуйста, разместите структуру базы данных, чем. – J0HN

+0

@john - Я думал, что ваше предложение - путь, но мне действительно нужно убедиться, что я только возвращаю комментарии от оригинального автора. Итак, комментарии от authorID = 3 к articleId = 1. Извиняюсь, если я не понял. Но спасибо за предложение! –

0

- вы можете использовать подзапрос

select * from comments WHERE articleId IN(1,2) 
and userId in (select userId from article where id in (1,2))