2013-04-05 4 views
0

Мне нужна помощь по слиянию двух сложных запросов MYSQL.Слияние двух сложных запросов MYSQL

Запрос 1:

SELECT p.* 
FROM posts p 
    INNER JOIN 
    (
     SELECT a.ID 
     FROM posts a 
       INNER JOIN post_tags b 
        ON a.ID = b.post_ID 
     WHERE a.post LIKE '%mmmm%' AND 
       b.tagname IN ('#test','#iseeyou') 
     GROUP BY ID 
     HAVING COUNT(DISTINCT b.tagname) = 2 
    ) sub ON p.ID = sub.ID 
ORDER BY p.upvotes DESC, p.unix_timestamp DESC 

Запрос 2:

SELECT p.*, ((upvotes + 1.9208)/(upvotes + downvotes) - 1.96 * SQRT((upvotes * downvotes) 
/(upvotes + downvotes) + 0.9604)/(upvotes + downvotes)) 
/(1 + 3.8416/(upvotes + downvotes)) AS ci_lower_bound 
FROM posts p WHERE upvotes + downvotes > 0 
AND p.unix_timestamp BETWEEN 1363023402 AND 1363109802 ORDER BY ci_lower_bound DESC 

Небольшое определение таблицы дается в SQL Fiddle

На самом деле, первый из которых является поисковый запрос, а второй дает самые популярные результаты, основанные на голосах за последние 24 часа, поэтому я хочу использовать поисковый запрос на основе формулы, используемой во втором, а также временной диапазон

+0

просто для любопытства :), почему у не использовать хранимую процедуру, чтобы сделать так – NetStarter

+0

почему вы хотите, чтобы объединить их вообще? – fancyPants

+0

@NetStarter Я не уверен, как использовать хранимую процедуру для этого. – coder101

ответ

0

С минимальными изменениями что-то вроде этого (если я понял, что вы хотите правильно)

SELECT p.*, ((upvotes + 1.9208)/(upvotes + downvotes) - 1.96 * SQRT((upvotes * downvotes) 
/(upvotes + downvotes) + 0.9604)/(upvotes + downvotes)) 
/(1 + 3.8416/(upvotes + downvotes)) AS ci_lower_bound 
FROM posts p 
    INNER JOIN 
    (
     SELECT a.ID 
     FROM posts a INNER JOIN post_tags b ON a.ID = b.post_ID 
     WHERE a.post LIKE '%mmmm%' AND b.tagname IN ('#test','#iseeyou') 
     GROUP BY ID 
     HAVING COUNT(DISTINCT b.tagname) = 2 
    ) sub ON p.ID = sub.ID 
WHERE upvotes + downvotes > 0 
AND p.unix_timestamp BETWEEN 1363023402 AND 1363109802 
ORDER BY ci_lower_bound DESC 

Возможно прикосновение более эффективным, чтобы поменять вокруг ИНЕКЕ на подвыборки (ведущий% на подобные не будет использовать индекс, следовательно, вероятно, более эффективным, чтобы присоединиться, что против легко индексируемой проверки на post_tags))

SELECT p.*, ((upvotes + 1.9208)/(upvotes + downvotes) - 1.96 * SQRT((upvotes * downvotes) 
/(upvotes + downvotes) + 0.9604)/(upvotes + downvotes)) 
/(1 + 3.8416/(upvotes + downvotes)) AS ci_lower_bound 
FROM posts p 
    INNER JOIN 
    (
     SELECT a.ID 
     FROM post_tags b STRAIGHT_JOIN posts a ON a.ID = b.post_ID 
     WHERE a.post LIKE '%mmmm%' AND b.tagname IN ('#test','#iseeyou') 
     GROUP BY ID 
     HAVING COUNT(DISTINCT b.tagname) = 2 
    ) sub ON p.ID = sub.ID 
WHERE upvotes + downvotes > 0 
AND p.unix_timestamp BETWEEN 1363023402 AND 1363109802 
ORDER BY ci_lower_bound DESC 
+0

. Я использовал то же, что вы предлагали, и получил пустой результат, но то, что я сделал, - это поиск в интервале времени, который не удовлетворял тэгам, поэтому думал, что я ошибался. И теперь, увидев ваш ответ, это просто поразило меня. Вы просветили меня, мой друг :) – coder101

+0

Как узнать разницу между производительностью двух версий, которые вы предложили? Я проверил с помощью «EXPLAIN», но это было похоже. Я имею в виду, что бы вы посоветовали мне пойти? – coder101

+1

Я бы надеялся, что MySQL обычно распознает проблему и оптимизирует ее. Но иногда это не удается сделать, поэтому иногда STRAIGHT_JOIN может быть полезен, чтобы заставить порядок JOIN – Kickstart

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