这是我的表的SQLFiddle 链接。
num
我基本上只想选择 Jack 和 Jill,因为表的最后两个s 条目foo
与user
它们各自的名称之间存在非零差异。
这怎么可能?
注意:顺便提一下,在我的foo
表中,我有大约 100000 行,所以如果有一种非常快速和快速的方法来检索数据会很好。
这是我的表的SQLFiddle 链接。
num
我基本上只想选择 Jack 和 Jill,因为表的最后两个s 条目foo
与user
它们各自的名称之间存在非零差异。
这怎么可能?
注意:顺便提一下,在我的foo
表中,我有大约 100000 行,所以如果有一种非常快速和快速的方法来检索数据会很好。
我更喜欢使用limit
偏移量来获取两个最新值。令人高兴的是,您的表格有一个id
用于确定顺序的列。
select user,
(select num from foo f2 where f2.user = f.user order by f2.id desc limit 1
) lastval,
(select num from foo f2 where f2.user = f.user order by f2.id desc limit 1, 2
) lastval2
from foo f
group by user
having lastval <> lastval2
这是一种方法(尽管我认为您更有可能加入用户的 id 而不是他们的名字!?!...
SELECT u.*
FROM
( SELECT x.*, COUNT(*) rank FROM foo x JOIN foo y ON y.user = x.user AND y.id >= x.id GROUP BY x.id)a
LEFT
JOIN
( SELECT x.*, COUNT(*) rank FROM foo x JOIN foo y ON y.user = x.user AND y.id >= x.id GROUP BY x.id)b
ON b.user = a.user
AND b.num = a.num
AND b.rank = a.rank + 1
JOIN users u
ON u.user = a.user
WHERE b.id IS NULL
AND a.rank = 1;
我认为这个查询可以重写如下,这可能会更快......
SELECT u.*
FROM
( SELECT id
, user
, num
, @prev_user := @curr_user
, @curr_user := user
, @rank := IF(@prev_user = @curr_user, @rank+1, @rank:=1) rank
FROM foo
JOIN (SELECT @curr_user := null, @prev_user := null, @rank := 0) sel1
ORDER
BY user
, id DESC
) a
LEFT
JOIN
( SELECT id
, user
, num
, @prev_user := @curr_user
, @curr_user := user
, @rank := IF(@prev_user = @curr_user, @rank+1, @rank:=1) rank
FROM foo
JOIN (SELECT @curr_user := null, @prev_user := null, @rank := 0) sel1
ORDER
BY user
, id DESC
) b
ON b.user = a.user
AND b.num = a.num
AND b.rank = a.rank + 1
JOIN users u
ON u.user = a.user
WHERE b.id IS NULL
AND a.rank = 1;
基于草莓的第二个解决方案,我已经尝试过了。
SELECT user, MIN(num) AS MinNum, MAX(num) AS MaxNum
FROM ( SELECT id
, user
, num
, @prev_user := @curr_user
, @curr_user := user
, @rank := IF(@prev_user = @curr_user, @rank+1, 1) AS rank
FROM foo
JOIN (SELECT @curr_user := null, @prev_user := null, @rank := 1) sel1
ORDER BY user, id DESC
) AS Sub
WHERE rank <= 2
GROUP BY user
HAVING MinNum != MaxNum
这将详细信息列为子选择并拒绝排名大于 2 的位置(不幸的是,如果您尝试在子选择中检查,用户变量会给出奇怪的结果)。然后将结果按用户分组,并返回 num 的最小值和最大值。如果它们不同,则返回该行(并且由于每个用户只有 1 或 2 行,因此只有当返回 2 行并且它们具有不同的值时,最小值和最大值才会不同)。
这样做的好处是它避免了将 2 个 100000 个集合相互连接,并且只需要进行一次排名(尽管您希望 MySQL 无论如何都会优化这个 2nd 问题)。