【问题标题】:A somewhat complex mysql query一个有点复杂的mysql查询
【发布时间】:2011-05-29 06:36:22
【问题描述】:

我目前正在开发一个新闻数据库网站,但我似乎无法创建查询来选择 5 篇最热门的新闻文章。受此查询影响的数据库的 2 个表是:

  • 新闻 - 包含所有新闻项目(id、作者、消息等)
  • Rates - 包含新闻项目的所有评级(id、news_id、rating 等)

现在我的查询应该从表 Rates 中选择 5 个 news_ids,具有最高的平均评分和最多的选票(所以:按 AVG(Rating) 和 COUNT(*) 排序)。我首先尝试进行查询,并立即从 News 表中获取这些 news_ids 的所有信息(使用 WHERE id IN(--the query selection the 5 hottest news_ids--) 子句),但这返回了 MySql Version 的错误不能在 WHERE IN 子查询中使用 LIMIT。

好吧,我希望你能帮助我完成第一个必须选择这 5 个 news_id 的查询。我现在得到的查询(但没有完全工作)是:

SELECT news_id FROM 
              (SELECT news_id, AVG(rating) AS average_r, COUNT(*) AS amt_r 
                      FROM rates 
                      GROUP BY news_id 
                      ORDER BY average_r,amt_r 
                      DESC LIMIT 5
               ) AS news_rates

或在我的脚本的其余部分内容:

$get_hot_news_ids = mysql_query("SELECT news_id FROM 
        (SELECT news_id, AVG(rating) AS average_r, COUNT(*) AS amt_r 
         FROM rates 
         GROUP BY news_id 
         ORDER BY average_r,amt_r DESC LIMIT 5) AS news_rates");

    $first = 1;
    while($news_id     = mysql_fetch_assoc($get_hot_news_ids)) {
        if(!$first) {
            $hot_news_ids .= " ,";
        }else{
            $first = 0;
        }
        $hot_news_ids .= $news_id['news_id'];
    }
    //print_r($hot_news_ids);
    $get_hot_news = mysql_query("SELECT * FROM news 
        WHERE id IN($hot_news_ids) 
        ORDER BY FIELD(id, $hot_news_ids)");

【问题讨论】:

    标签: php mysql


    【解决方案1】:

    你确定average_r和amt_r都是降序排列吗?

    SELECT news_id FROM 
                  (SELECT news_id, AVG(rating) AS average_r, COUNT(*) AS amt_r 
                          FROM rates 
                          GROUP BY news_id 
                          ORDER BY average_r DESC, amt_r DESC
                          LIMIT 5
                   ) AS news_rates
    

    【讨论】:

    • 刚刚修好了!如此愚蠢的错误,非常感谢,它现在正在工作:)。
    【解决方案2】:

    试试这个:

    SELECT TOP 5 N.id, N.author, N.message, AVG(R.rating) AS rate, COUNT(R.news_id) AS votes
    FROM       news  N
    INNER JOIN rates R ON N.id = R.news_id
    GROUP BY N.id, N.author, N.message
    ORDER BY rate, votes
    

    【讨论】:

    • MySql 不支持TOP n 子句。
    • 这看起来像MS-SQL,我不认为mysql有“SELECT TOP”。
    • 感谢您的回复。您提供的 MySql 查询给了我一个 mysql_error: You have an error in your SQL syntax;检查与您的 MySQL 服务器版本相对应的手册,以了解在 '5 N.id, N.author, N.message, AVG(R.rating) AS rate, COUNT(R.news_id) AS votes F' 附近使用的正确语法在第 1 行。
    • 哇,不是吗?甚至在 5.xx 版本中都没有?我已经使用 MySQL 完成了一些(小)项目,很难相信到目前为止我从来不需要 TOP n 子句,只是发现它不受支持(还没有?)。
    • @PPC-Coder:这不是面向 MS-SQL 的……它也适用于 Oracle。实际上,它适用于(几乎)我迄今为止工作的所有 RDBMS。我真的很惊讶,像 MySQL 这样成熟的数据库竟然没有支持它。
    【解决方案3】:

    您可以改用 join,这将允许 limit:

    SELECT *
    FROM news n JOIN (
        SELECT news_id, AVG(rating) AS average_r, COUNT(*) AS amt_r 
        FROM rates 
        GROUP BY news_id 
        ORDER BY average_r,amt_r DESC 
        LIMIT 5
      ) top5 ON n.news_id = top5.news_id
    ORDER BY top5.average_r,top5.amt_r 
    

    注意:您可能希望将查询更改为 ORDER BY average_r DESC, amt_r DESC 以获得最高评级的项目,而不是最低评级。

    【讨论】:

    • 非常感谢,但是 PPC-Coder 已经给出了基本的解决方案,我仍然很欣赏使用 join 的解释和替代查询(不太了解 join 的第一个)。
    猜你喜欢
    • 1970-01-01
    • 2015-01-28
    • 1970-01-01
    • 2014-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多