简体   繁体   中英

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. 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 .

in order to use aggregate functions (min, max, ...) you need grouping. 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, unfortunately allows this behavior, making it harder to notice that you forgot the group by clause needed to generate a row per user:

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.

You should use GROUP BY with some field from u , like id .

Grouping is a waste of resources. Use nested select statement instead. 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; '

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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