SQL Group问题 - 选择哪一行进行分组

时间:2010-07-21 16:10:51

标签: sql mysql group-by aggregate-functions

我有一张表来跟踪序列号和与所述序列号相关的许可证数量。客户可以重新许可一个方框,增加或减少用户数量,并且只对更改的金额进行计费。

存在以下表格结构:

id - Auto Incrementing ID
serial - The serial number
numusers - the number of licenses
date - The date that the request was submitted, with the highest date being the number of users currently licensed

我有以下查询来选择已更新的许可证,如果许可证仅重新提交一次,则它可以正常工作。如果已多次重新提交,则会返回对先前更新的引用,以及之前的所有更新。

SELECT p.id as id, c.id as oldid, p.numusers-c.numusers AS dif, p.date, c.date
FROM `licenses` AS p 
JOIN `licenses` AS c ON p.serial = c.serial 
                    AND p.date > c.date 
                    AND p.id <> c.id
WHERE p.id = 156
#GROUP BY p.id

这是数据集:

id  serial  numusers    date
26  1234    500         2010-07-14
34  1234    600         2010-07-15
156 1234    500         2010-07-21

当我运行查询时,我得到以下内容:

id      oldid       dif         date          date
156     26          0          2010-07-21    2010-07-14
156     34          -100       2010-07-21    2010-07-15

如果我在查询中取消注释GROUP BY子句,我得到oldid为26的行。我怎么只选择具有最新日期的行(oldid为34的行)?我可以使用ORDER BY和LIMIT 1,但我也希望能够从没有WHERE子句的整个表中进行选择。

我正在使用MySQL 5.1。

2 个答案:

答案 0 :(得分:1)

派生表是否可以使用;类似......

SELECT *
    FROM (SELECT p.id as id,
                 c.id as oldid,
                 p.numusers-c.numusers AS dif,
                 p.date,
                 c.date
              FROM `licenses` AS p JOIN `licenses` AS c ON p.serial = c.serial 
                   AND p.date > c.date 
                   AND p.id <> c.id
              ORDER BY oldid DESC) AS inner_table
    GROUP BY id;

答案 1 :(得分:1)

也许你想要的是:

select p.id, c.id as priorid, p.numusers-c.numusers AS dif, p.date, c.date as priordate    
from licenses p
join licenses c on c.serial=p.serial
  and c.date=(select max(date) from licenses ref where ref.serial=p.serial
    and ref.date<p.date)
order by p.serial

我总是发现这是一个相当讨厌的SQL限制,说“从字段Y的最大值获取记录字段X”需要我读取表格一次以找到Y的最大值嵌入式查询,然后再次读取它以重新找到具有该值的记录并检索我想要的其他值。

如果同一个Serial有三个记录,则上面应该在输出上给出两个“差异”行。我想这就是你想要的。如果给定的Serial只有一条记录,则上面的代码不会输出,也可能不是。