合并两个复杂的MYSQL查询

时间:2013-04-05 13:24:31

标签: 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小时内的投票给出最受欢迎的结果,所以我想根据第二个中使用的公式和时间使用搜索查询范围

1 个答案:

答案 0 :(得分: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