Php 用于选择最大元素的MySQL查询

Php 用于选择最大元素的MySQL查询,php,sql,mysql,Php,Sql,Mysql,我有一个表,有4列:place\u id,username,counter,last\u checkin 我正在写一个基于报到的系统,我试图得到一个查询,它会给我每个地方的“市长”。市长是登记人数最多的人,如果超过最小值上次登记人数则获胜 例如,如果我有: place_id, username, counter, last_checkin 123, tom, 3 , 13/4/10 123, jill, 3, 14/4/10 36

我有一个表,有4列:
place\u id
username
counter
last\u checkin

我正在写一个基于报到的系统,我试图得到一个查询,它会给我每个地方的“市长”。市长是登记人数最多的人,如果超过最小值
上次登记人数
则获胜

例如,如果我有:

place_id, username, counter, last_checkin
 123,     tom,       3 ,      13/4/10
 123,     jill,      3,       14/4/10
 365,     bob,       2,       15/4/10
 365,     alice,     1,       13/4/10
我希望结果是:

123, tom
365, bob
我在PHP代码中使用它


以下是测试数据:

CREATE TABLE `my_table` ( `place_id` int(11), `username` varchar(50), `counter` int(11), `last_checkin` date);
INSERT INTO `my_table` VALUES (123,'tom',3,'2010-04-13'),(123,'jill',3,'2010-04-14'),(365,'bob',2,'2010-04-15'),(365,'alice',1,'2010-04-13');

SELECT
    place_id,
    (SELECT username
         FROM my_table MT2
         WHERE MT2.place_id = MT1.place_id
         ORDER BY counter DESC, last_checkin ASC
         LIMIT 1) AS mayor
    FROM my_table MT1
    GROUP BY place_id;

编辑为Unreason建议对最后一次签入按升序排列。

我会写Brian的相关查询。然而,我发现了这一点,它的性能可能会因数据而异

SELECT
    mt1.place_id,
    mt1.username
FROM 
    my_table mt1 LEFT JOIN my_table mt2 
        ON mt1.place_id = mt2.place_id AND
           (mt1.counter < mt2.counter OR 
            (mt1.counter = mt2.counter AND mt1.last_checkin > mt2.last_checkin)
           )
WHERE 
    mt2.place_id IS NULL
选择
mt1.1位置标识,
mt1.username
从…起
my_表mt1左连接my_表mt2
在mt1.place\u id=mt2.place\u id上
(mt1.计数器mt2.last_checkin)
)
哪里
mt2.place\u id为空

根据特定条件,它使用左连接来获得顶级记录。

这听起来像是我听说过的最公然的复制:)什么是foursquare?哈哈:)只是开玩笑。显然,我使用了来自foursquare的术语来让问题更容易理解:)为什么最大(place_id)?因为max(counter)?稍微更正$data=query(“按max(counter)ORDER按上次签入说明从表组中选择place_id、username”);对不起,我弄错了,我把它修好了。发生:)āris,您的查询不满足所需的条件。它将选择计数器的最大值,然后从组中随机选择用户名,因此从样本数据中选择tom或jill作为place_id 123。From-'服务器可以从组中自由返回任何值,因此除非所有值都相同,否则结果是不确定的。'此外,查询不需要返回最大值(计数器),但需要返回位置\u id。最后一次\u检查应为升序,引述:“如果有超过1个超过最后一次登记的最低赢家”,我一直是一个subquerian,因为我发现加入会让我头疼。但是你的解决方案也是正确的,我怀疑在这个网站上,联合主义者占大多数。我认为不会有任何性能差异,因为查询优化程序可以在认为合适的情况下将子查询重写为连接。事实上,我相信在这种情况下,子查询在一些“普通”数据集上会执行得更快,mysql可能会对复杂的连接感到困惑,它不知道如何将其重写为子查询,也不知道如何有效地使用索引。然而,我喜欢这个原则(对我来说是新鲜的),我既不是subquerian也不是joinists,而是pro-choice:),所以我提供了一个不同的解决方案。
SELECT
    mt1.place_id,
    mt1.username
FROM 
    my_table mt1 LEFT JOIN my_table mt2 
        ON mt1.place_id = mt2.place_id AND
           (mt1.counter < mt2.counter OR 
            (mt1.counter = mt2.counter AND mt1.last_checkin > mt2.last_checkin)
           )
WHERE 
    mt2.place_id IS NULL