简体   繁体   English

使用带有MAX()和MIN()函数的SQL LEFT JOIN

[英]Using an SQL LEFT JOIN with the MAX() and MIN() functions

Let's assume I have the following two tables: 我们假设我有以下两个表:

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;

What I'm trying to do here is get a query for all users with the first day they logged in and the last day they logged in. The query I was executing to achieve this looks like the following: 我在这里要做的是在他们登录的第一天和他们登录的最后一天获得所有用户的查询。我执行此查询的查询如下所示:

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

The problem is that because of the use of MIN() and MAX() , I'm only receiving one row back in the entire result. 问题是因为使用MIN()MAX() ,我只在整个结果中收到一行。 I'm sure it's my use of those functions that's causing this. 我确信这是我使用那些引起这种情况的功能。 I should have one row per user, even if they do not have any login entries. 每个用户应该有一行,即使他们没有任何登录条目。 This is the reason for me using a LEFT JOIN vs an INNER JOIN . 这就是我使用LEFT JOININNER JOIN

in order to use aggregate functions (min, max, ...) you need grouping. 为了使用聚合函数(min,max,...),您需要分组。 Try something like this: 尝试这样的事情:

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

Any sensible database except MySQL would have given you an error on mixing row-terms and aggregate terms, making the error clearer. 除MySQL之外的任何敏感数据库都会在混合行项和聚合项时给出错误,从而使错误更加清晰。 MySQL, unfortunately allows this behavior, making it harder to notice that you forgot the group by clause needed to generate a row per user: 遗憾的是,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

MIN and MAX are aggregate functions. MIN和MAX是聚合函数。

You should use GROUP BY with some field from u , like id . 您应该使用GROUP BY与某些字段从u ,像id

Grouping is a waste of resources. 分组是浪费资源。 Use nested select statement instead. 请改用嵌套的select语句。 eg. 例如。

`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; '

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM