代码之家  ›  专栏  ›  技术社区  ›  jerebear

欺骗性MySQL查询

  •  4
  • jerebear  · 技术社区  · 14 年前

    因此,我不认为自己是MySQL的新手,但这一次却让我左右为难:

    我有一个留言板,我想拉一个按线程ID分组的所有最新文章的列表。

    这是桌子:

    MB_Posts
    -ID
    -Thread_ID
    -Created_On (timestamp)
    -Creator_User (user_id)
    -Subject
    -Contents
    -Edited (timestamp)
    -Reported
    

    我尝试过很多不同的方法来保持简单,但我希望社区能在这方面提供帮助。

    只是为了解决这个问题……这个问题并不像预期的那样有效:

    SELECT * FROM MB_Posts GROUP BY Thread_ID ORDER BY ID DESC
    

    预期结果:

    一组最新的日志,每个线程ID一个

    7 回复  |  直到 14 年前
        1
  •  3
  •   Unreason    14 年前

    Group By覆盖Order By(无例外)。

    SELECT * 
    FROM MB_Posts 
    WHERE ID IN (SELECT MAX(ID) FROM MB_Posts GROUP BY Thread_ID)
    

    应该给你所需要的。

    有关详细信息,请阅读 hidden columns in group by (在原始查询中,除了线程ID之外的所有列都被隐藏)

        2
  •  0
  •   mkj java seeker    14 年前

    当你使用 GROUP BY ,您必须在 SELECT 声明的一部分。

        3
  •  0
  •   vickirk    14 年前

    Group By期望每个唯一的Group By返回一行,例如

    SELECT COUNT(*) FROM mb_post GROUP BY thread_id;
    

    将返回每个线程中的日志数。

    您需要按线程进行排序,然后以编程方式按您想要的方式处理“分组”,例如。

    for (row in rows) {
        print("<tr><th>");
        if (row["thread_id"] != prev_id) {
          print(thread_id)
          prev_id = thread_id;
        }
        print("</th>")
    
        4
  •  0
  •   Jage    14 年前

    好的,我有个建议。让我知道:

    SELECT 
        MB_Posts.*, 
        (SELECT 
            GROUP_CONCAT(CreatedOn ORDER BY CreatedOn DESC) 
            FROM MB_Posts AS P 
            WHERE P.Thread_ID = MB_Posts.Thread_ID) 
        AS `sort`  
    FROM MB_Posts 
    ORDER BY `sort` DESC, CreatedOn DESC 
    
        5
  •  0
  •   Kevin Vaughan    14 年前

    试一试,看看是否符合你的要求。这将显示最近100篇文章,结果将按它们所属的线程进行排序。

    SELECT MB_Posts.* 
      FROM MB_Posts 
      INNER JOIN (
        SELECT ID FROM MB_Posts ORDER BY Created_On DESC LIMIT 0, 100
      ) as MostRecentPosts ON MB_Posts.ID = MostRecentPosts.ID
      ORDER BY Thread_ID, Created_On DESC;
    

    根据您的修订版“一组最新文章,每个线程一个ID”,可以使用少量concat和compare magic创建从子查询创建的表。这将取决于您的列类型,但大多数情况下都可以。这两种解决方案的思想都是使用子查询来处理聚合过程并确定所需记录的ID,然后根据该子查询的结果联接表以检索行的其余数据。

    SELECT MB_Posts.* 
      FROM MB_Posts 
      INNER JOIN (
        SELECT TRIM(LEADING '0' FROM
          SUBSTRING(MAX(CONCAT(UNIX_TIMESTAMP(Created_On), LPAD(ID,15,'0'))), -15)) AS ID
        FROM MB_Posts 
        GROUP BY Thread_ID
      ) as MostRecentPostPerThread ON MB_Posts.ID = MostRecentPostPerThread.ID
      ORDER BY Thread_ID, Created_On DESC;
    
        6
  •  0
  •   mspir    14 年前

    另一种方法是:

    SELECT * FROM mb_posts ORDER BY ID DESC
    
    threadsHistory = array();
    while (row)
    {
        if (row) NOT IN threadsHistory
        {
             add values to array (for example thread_ID and postID) 
             count++;
        }
        if count == 10 break;
    }
    

    这不完全是一个好的和干净的方式,但它应该有点扭曲工作。

        7
  •  0
  •   J M D    14 年前

    隐马尔可夫模型。。。是否创建或编辑确定“最新”?

    假设创造了什么是需要的:

    从mb_posts group by thread_id中选择thread_id,max(created_on);

    给出每个线程的最新时间戳。半连接这些到MB日志 有点像

    从mb_帖子中选择* join(select thread_id,max(created_on)as created_on from mb_posts group by thread_id)最近 使用(thread_id,created_on);