我们假设我有以下两个表:
CREATE TABLE users (
id MEDIUMINT NOT NULL AUTO_INCREMENT,
name CHAR(30) NOT NULL,
PRIMARY KEY (id)
) ENGINE=MyISAM;
CREATE TABLE logins (
user_id NOT NULL,
day DATE NOT NULL,
PRIMARY KEY (`user_id, `day`)
) ENGINE=MyISAM;
我在这里要做的是在他们登录的第一天和他们登录的最后一天获得所有用户的查询。我执行此操作的查询如下所示:
SELECT u.id AS id, u.name AS name, MIN(l.day) AS first_login,
MAX(l.day) AS last_login
FROM users u
LEFT JOIN logins l ON u.id = l.user_id
问题在于,由于使用了MIN()
和MAX()
,我只在整个结果中收到一行。我确信这是我使用那些引起这种情况的功能。每个用户应该有一行,即使他们没有任何登录条目。这就是我使用LEFT JOIN
与INNER JOIN
的原因。
答案 0 :(得分:2)
为了使用聚合函数(min,max,...),您需要分组。尝试这样的事情:
SELECT u.id AS id, u.name AS name, MIN(l.day) AS first_login, MAX(l.day) AS last_login
FROM users u
LEFT JOIN logins l ON u.id = l.user_id
GROUP BY u.id
答案 1 :(得分:1)
除MySQL之外的任何敏感数据库都会在混合行项和聚合项时给出错误,从而使错误更加清晰。不幸的是,MySQL允许这种行为,因此很难注意到你忘记了为每个用户生成一行所需的group by
子句:
SELECT u.id AS id,
u.name AS name,
MIN(l.day) AS first_login,
MAX(l.day) AS last_login
FROM users u
LEFT JOIN logins l ON u.id = l.user_id
GROUP BY u.id, u.name -- missing in the original query
答案 2 :(得分:0)
MIN和MAX是聚合函数。
您应该将GROUP BY
与u
中的某个字段一起使用,例如id
。
答案 3 :(得分:0)
分组是浪费资源。 请改用嵌套的select语句。 例如。
`SELECT u.id AS id,
u.name AS name,
(select max(logins.day) from logins where logins.user_id=u.id) as last_login
from users u; '