mysql加入分组内的最小值

时间:2018-11-08 09:05:39

标签: mysql sql left-join

我正在尝试编写查询。

我的表格是:

+----+---------+------------+
| id | user_id |    date    |
+----+---------+------------+
|  1 |       1 | 2013-04-01 |
|  2 |       1 | 2017-01-01 |
|  3 |       1 | 2018-07-01 |
|  4 |       2 | 2018-09-01 |
|  5 |       2 | 2018-05-01 |
|  6 |       3 | 2018-10-01 |
|  7 |       1 | 2012-01-01 |
|  8 |       3 | 2016-06-01 |
|  9 |       3 | 2011-01-01 |
| 10 |       1 | 2000-01-01 |
+----+---------+------------+

预期结果:

+----+---------+------------+-------------+
| id | user_id |    date    | first_login |
+----+---------+------------+-------------+
|  1 |       1 | 2013-04-01 | 2000-01-01  |
|  2 |       1 | 2017-01-01 | 2000-01-01  |
|  3 |       1 | 2018-07-01 | 2000-01-01  |
|  4 |       2 | 2018-09-01 | 2018-05-01  |
|  5 |       2 | 2018-05-01 | 2018-05-01  |
|  6 |       3 | 2018-10-01 | 2011-01-01  |
|  7 |       1 | 2012-01-01 | 2000-01-01  |
|  8 |       3 | 2016-06-01 | 2011-01-01  |
|  9 |       3 | 2011-01-01 | 2011-01-01  |
| 10 |       1 | 2000-01-01 | 2000-01-01  |
+----+---------+------------+-------------+

有可能吗? 在我看来,这是联接的组合!

我尝试过,但是没有用。执行无止境。

CREATE TABLE CONNEXIONS
    (`id` int, `user_id` int, `date` date)
;

INSERT INTO CONNEXIONS
    (`id`, `user_id`, `date`)
  VALUES
    (1, 1, '2013-04-01'),
    (2, 1, '2017-01-01'),
    (3, 1, '2018-07-01'),
    (4, 2, '2018-09-01'),
    (5, 2, '2018-05-01'),
    (6, 3, '2018-10-01'),
    (7, 1, '2012-01-01'),
    (8, 3, '2016-06-01'),
    (9, 3, '2011-01-01'),
    (0, 1, '2000-01-01')
  ;


SELECT  conn.*, c.first_login
FROM CONNEXIONS AS conn

INNER JOIN (
    SELECT MIN(conn.date) AS first_login, user_id
    FROM CONNEXIONS AS conn
    GROUP BY conn.user_id
) c ON (conn.user_id = c.user_id)

编辑: 我在查询中犯了一个错误,用MAX代替MIN,用client_id代替user_id。

4 个答案:

答案 0 :(得分:3)

您可以使用correlated子查询,并且需要MIN()而不是MAX()

SELECT CONN.*,
       (SELECT MIN(conn1.date)
        FROM CONNEXIONS conn1
        WHERE conn1.user_id = conn.user_id
       ) AS first_login
FROM CONNEXIONS conn;

答案 1 :(得分:2)

  • 我相信first_login将是最小连接日期,而不是最大连接日期。
  • 您混淆了别名。我已经解决了。

尝试:

SELECT  conn1.*, c.first_login
FROM CONNEXIONS AS conn1
INNER JOIN (
    SELECT MIN(conn2.date) AS first_login, conn2.user_id
    FROM CONNEXIONS AS conn2
    GROUP BY conn2.user_id
) c ON (conn1.user_id = c.user_id)

结果

| id  | user_id | date       | first_login |
| --- | ------- | ---------- | ----------- |
| 1   | 1       | 2013-04-01 | 2000-01-01  |
| 2   | 1       | 2017-01-01 | 2000-01-01  |
| 3   | 1       | 2018-07-01 | 2000-01-01  |
| 4   | 2       | 2018-09-01 | 2018-05-01  |
| 5   | 2       | 2018-05-01 | 2018-05-01  |
| 6   | 3       | 2018-10-01 | 2011-01-01  |
| 7   | 1       | 2012-01-01 | 2000-01-01  |
| 8   | 3       | 2016-06-01 | 2011-01-01  |
| 9   | 3       | 2011-01-01 | 2011-01-01  |
| 0   | 1       | 2000-01-01 | 2000-01-01  |

View on DB Fiddle

答案 2 :(得分:0)

只需使用min()代替max(),您就需要按user_id分组

SELECT  conn.*, c.first_login
FROM CONNEXIONS

INNER JOIN (
    SELECT min(conn.date) AS first_login, user_id
    FROM CONNEXIONS AS conn
    GROUP BY conn.user_id
) c ON (conn.user_id = c.user_id)

答案 3 :(得分:0)

值得指出的是,在MySQL 8+中,您将使用标准的窗口函数:

SELECT c.*,
       MIN(c.date) OVER (PARTITION BY c.user_id) as first_login
FROM CONNEXIONS c;