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

MySQL组并从每个组中只选择第一个[重复]

  •  0
  • Attie  · 技术社区  · 6 年前

    这个问题已经有了答案:

    我要执行一个查询,该查询将只选择给定组中的最新项。


    在本例中,我跟踪的是货车:

    • 每次他们回到基地 check-in 记录了信息-里程等。。。
    • 每次他们送货时 delivery 有记录-客户等…

    这张表让我们知道一个给定的 van 是的。数据可以通过查询生成,也可以按我们的方式存储——这不是问题所在。

     id | checkin_id | delivery_id | van_id
    ----+------------+-------------+--------
     24 | 15         | NULL        | 3
     25 | NULL       | 28          | 3
     26 | 16         | NULL        | 4
     27 | NULL       | 29          | 3
     28 | NULL       | 30          | 4
     29 | 17         | NULL        | 5
    

    我可以通过查询 ... WHERE van_id=3; -很好。

    相反,我希望能够得到 vans 最新的” 事件 “。结果是:

     id | checkin_id | delivery_id | van_id
    ----+------------+-------------+--------
     27 | NULL       | 29          | 3
     28 | NULL       | 30          | 4
     29 | 17         | NULL        | 5
    

    我跳到下面的问题:

    SELECT * FROM `history` GROUP BY `van_id`;
    

    但这将返回以下错误:

    #1055-选择列表的表达式1不在GROUP BY子句中,并且包含未聚合的列“database.history.checkin_id”,它在功能上不依赖GROUP BY子句中的列;这与SQL_mode=only_full_group_by不兼容

    读完之后,我明白了这是怎么回事,不得不承认我的sql有些过时了- 我要返回组中的哪些项?

    添加 checkin_id delivery_id GROUP BY 只是转移问题-最终我得到的是同一组数据,只是排序不同。


    This answer 激发了我的兴趣,这张图片确实有助于清晰地勾勒出问题的轮廓,谢谢@azerafati!

    我想用 FIRST() LAST() 聚合函数- but MySQL doesn't appear to have them .

    如何在不进行处理的情况下复制此行为 全部的 我的申请中的数据?

    2 回复  |  直到 6 年前
        1
  •  2
  •   O. Jones    6 年前

    我想你的 id 值是唯一的,后面的记录比前面的记录具有更高的值。

    您需要使用一个子查询来获取最新的 身份证件 对于每辆货车:

             SELECT MAX(id) id, van_id
               FROM history
              GROUP BY van_id
    

    然后将其加入到详细信息查询中。

     SELECT h.*
       FROM history h
       JOIN (
             SELECT MAX(id) id, van_id
               FROM history
              GROUP BY van_id
            ) m ON h.id = m.id AND h.van_id = m.van_id
    

    但是,由于id值是唯一的,所以可以进一步简化。

     SELECT h.*
       FROM history h
       JOIN (
             SELECT MAX(id) id
               FROM history
              GROUP BY van_id
            ) m ON h.id = m.id
    
        2
  •  2
  •   Uueerdo    6 年前

    我本来打算将此标记为重复项,因为问题实际上被问得相当频繁,但我发现这些问题/答案似乎很难搜索;因此这里是通用模板:

    SELECT t.*
    FROM theTable AS t
    INNER JOIN (
       SELECT groupingValue, MIN(someValue) AS lowestValue
       FROM theTable
       GROUP BY groupingValue
    ) AS rIdent ON rIdent.groupingValue = t.groupingValue AND rIdent.lowestValue= t.someValue
    

    最低的 在你的特殊情况下是min(id)…哦,糟糕;你的问题是第一个,但细节是最新的(我将解释为最后一个),所以只使用MAX而不是min。 …而“groupingValue”是van_id。

    编辑:如果分组字段和用于标识最低/第一/最高/最近的字段上有索引,则查询应该相当高效。