2013-04-05 116 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 2013-04-05 13:27:25

+0

为什么要合并他们在所有? – fancyPants 2013-04-05 13:27:53

+0

@NetStarter我不知道如何使用存储过程。 – coder101 2013-04-05 13:29:09

回答

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 

可能是一个触摸更有效地交换在子查询的WHERE子句周围(领导%上等不使用索引,因此可能更有效的参与,对上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 2013-04-05 15:35:27

+0

我如何找出你建议的两个版本的性能之间的区别?我用'EXPLAIN'检查过,但它看起来一样。我的意思是你会建议我应该怎么办? – coder101 2013-04-05 15:45:07

+1

我希望通常MySQL会认识到这个问题并优化它。但有时它不能这样做,因此偶尔STRAIGHT_JOIN可以用来强制JOIN – Kickstart 2013-04-05 15:51:22