2011-01-25 3 views
1

У меня есть следующий сценарий:mysql где IN на большом наборе данных или Looping?

Table 1: 

articles 

id article_text category author_id 
1 "hello world" 4    1 
2 "hi"    5    2 
3 "wasup"   4    3 


Table 2 

authors 

id name  friends_with 
1 "Joe"  "Bob" 
2 "Sue"  "Joe" 
3 "Fred"  "Bob" 

Я хочу знать, общее число авторов, которые являются друзьями с «Bob» для данной категории.

Так, например, для категории 4 столько авторов, которые дружат с «Боб».

В таблице авторов довольно большой, в некоторых случаях, у меня есть миллион авторы, которые являются друзьями с «Bob»

Так что я пробовал:

Получить список авторов, которые являются друзьями с Бобом, и затем прокрутите их и получите счетчик для каждой из них данной категории и суммируйте все это вместе в моем коде.

Проблема с этим подходом заключается в том, что он может генерировать миллион запросов, хотя они очень быстрые, кажется, что должен быть лучший способ.

Я думал о попытке получить список авторов, дружащих с bob, а затем создав предложение IN с этим списком, но я боюсь, что это сдует память, разрешенную в наборе запросов.

Похоже, что это распространенная проблема. Есть идеи?

благодаря

+0

Я не знаю, это настоящий образец, но я думаю, что отношения дружбы многим многим, и вы должны хранить эти данные в отдельной таблице авторов. – adopilot

ответ

1
SELECT COUNT(DISTINCT auth.id) 
FROM authors auth 
INNER JOIN articles art ON auth.id = art.author_id 
WHERE friends_with = 'bob' AND art.category = 4 

Count (Distinct a.id) требуется в качестве статей может ударить несколько строк для каждого автора.

Но если у вас есть какой-либо контроль над базой данных, я бы использовал таблицу ссылок для friends_with, так как ваше решение cussrent либо должно использовать разделенный запятыми список имен, которые будут катастрофическими для производительности, и требуют совершенно другого запроса или каждого автора может быть только один друг.

Друзья

ID friend_id

то запрос будет выглядеть следующим образом

SELECT COUNT(DISTINCT auth.id) 
FROM authors auth 
INNER JOIN articles art ON auth.id = art.author_id 
INNER JOIN friends f ON auth.id = f.id 
INNER JOIN authors fauth ON fauth.id = f.friend_id 
WHERE fauth.name = 'bob' AND art.category = 4 

Его более сложный, но позволит многим друзьям, просто вспомните, это построить звонки на 2 строки в друзья для каждой пары, одна от joe до bob и одна от bob до joe.

Вы можете построить его по-другому, но это сделает запрос еще более сложным.

+0

Count (DISTINCT id), это обычная вещь, которую мы забываем +1 – Harish

0

Может быть что-то вроде

select fr.name, 
     fr.id, 
     au.name, 
     ar.article_text, 
     ar.category, 
     ar.author_id 
from authors fr, authors au, articles ar 
where fr.id = ar.author_id 
and au.friends_with = fr.name 
and ar.category = 4 ; 

Просто граф ...

select count(distinct fr.name) 
from authors fr, authors au, articles ar 
where fr.id = ar.author_id 
and au.friends_with = fr.name 
and ar.category = 4 ; 
0

версия без использования соединений (надеюсь, будет работать!)

SELECT COUNT (отличный идентификатор) от авторов где friends_with = 'Bob' и идентификатор в (выберите author_id из статей, где категория = 4)

Я нашел, что это легче понять заявление с 'IN', когда после Я начал с SQL.

Смежные вопросы