>데이터 베이스 >MySQL 튜토리얼 >MySQL - GROUP BY 그룹화를 통해 필드 샘플 코드 세부 정보의 최대값 가져오기

MySQL - GROUP BY 그룹화를 통해 필드 샘플 코드 세부 정보의 최대값 가져오기

黄舟
黄舟원래의
2018-05-15 14:14:583390검색

MySQL - GROUP BY 샘플 코드 세부 정보를 그룹화하여 최대 필드 값 얻기:

사용자 로그인 기록 정보를 쿼리해야 하는 비즈니스 시나리오가 있고 테이블 구조가 있다고 가정합니다.

CREATE TABLE `tb` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `uid` int(11) NOT NULL,
  `ip` varchar(16) NOT NULL,
  `login_time` datetime,
  PRIMARY KEY (`id`),
  KEY (`uid`)
);

추가 테스트 데이터:

INSERT INTO tb SELECT null, 1001, '192.168.1.1', '2017-01-21 16:30:47';
INSERT INTO tb SELECT null, 1003, '192.168.1.153', '2017-01-21 19:30:51';
INSERT INTO tb SELECT null, 1001, '192.168.1.61', '2017-01-21 16:50:41';
INSERT INTO tb SELECT null, 1002, '192.168.1.31', '2017-01-21 18:30:21';
INSERT INTO tb SELECT null, 1002, '192.168.1.66', '2017-01-21 19:12:32';
INSERT INTO tb SELECT null, 1001, '192.168.1.81', '2017-01-21 19:53:09';
INSERT INTO tb SELECT null, 1001, '192.168.1.231', '2017-01-21 19:55:34';

테이블 데이터:

+----+------+---------------+---------------------+
| id | uid  | ip            | login_time          |
+----+------+---------------+---------------------+
| 1  | 1001 | 192.168.1.1   | 2017-01-21 16:30:47 |
| 2  | 1003 | 192.168.1.153 | 2017-01-21 19:30:51 |
| 3  | 1001 | 192.168.1.61  | 2017-01-21 16:50:41 |
| 4  | 1002 | 192.168.1.31  | 2017-01-21 18:30:21 |
| 5  | 1002 | 192.168.1.66  | 2017-01-21 19:12:32 |
| 6  | 1001 | 192.168.1.81  | 2017-01-21 19:53:09 |
| 7  | 1001 | 192.168.1.231 | 2017-01-21 19:55:34 |
+----+------+---------------+---------------------+

마지막 로그인 시간만 확인하려는 경우 사용자의 경우 간단히 다음과 같이 작성할 수 있습니다.

SELECT uid, max(login_time)
FROM tb
GROUP BY uid;
+------+---------------------+
| uid  | max(login_time)       |
+------+---------------------+
| 1001 | 2017-01-21 19:55:34 |
| 1002 | 2017-01-21 19:12:32 |
| 1003 | 2017-01-21 19:30:51 |
+------+---------------------+

사용자의 마지막 로그인에 대한 다른 정보도 쿼리해야 하는 경우 이 SQL을 사용하여 다음과 같이 작성할 수 없습니다.

-- 错误写法
SELECT uid, ip, max(login_time)
FROM tb
GROUP BY uid;
-- 错误写法

이런 문장은 SQL 표준은 아니지만 MySQL 데이터베이스에서는 실행은 성공했지만 반환값은 알 수 없다
(sql_mode가_full_group_by로만 켜져 있으면 실행이 성공하지 못한다.)

<br/>

아마도 ip 필드는 uid 그룹 이전의 첫 번째 필드를 차지할 것입니다. row의 값은 분명히 필수 정보가 아닙니다
Writing 1
Write a subquery:

SELECT a.uid, a.ip, a.login_time
FROM tb a
WHERE a.login_time in (
SELECT max(login_time)
FROM tb
GROUP BY uid);

Writing 2
아니면 글을 바꾸세요:

SELECT a.uid, a.ip, a.login_time
FROM tb a
WHERE a.login_time = (
SELECT max(login_time)
FROM tb
WHERE a.uid = uid);

그런데 테스트해봤습니다
5.6 이전 버전에서는 ②의 이 SQL 문의 실행 계획은 데이터 양이 많을 때 적합하지 않습니다. , 시각적 성능이 좋지 않습니다.
버전 5.6 이상에서는 ②이 SQL을 작성하는 것이 훨씬 빨라지고 실행 계획도 변경되었습니다.
5.5.50:

+----+--------------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type        | table | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+--------------------+-------+------+---------------+------+---------+------+------+-------------+
| 1  | PRIMARY            | a     | ALL  | NULL             | NULL  | NULL      | NULL | 7    | Using where |
| 2  | DEPENDENT SUBQUERY | tb    | ALL  | uid           | NULL  | NULL      | NULL | 7    | Using where |
+----+--------------------+-------+------+---------------+------+---------+------+------+-------------+

5.6.30:

+----+--------------------+-------+------+---------------+------+---------+------------+------+-------------+
| id | select_type        | table  | type | possible_keys | key  | key_len | ref       | rows  | Extra      |
+----+--------------------+-------+------+---------------+------+---------+------------+------+-------------+
| 1  | PRIMARY            | a     | ALL  | NULL              | NULL | NULL      | NULL        | 7    | Using where |
| 2  | DEPENDENT SUBQUERY | tb    | ref  | uid           | uid  | 4       | test.a.uid | 1    | NULL           |
+----+--------------------+-------+------+---------------+------+---------+------------+------+-------------+

쓰기 3
조인으로 직접 변경하면 성능이 더 좋아질 것입니다:

SELECT a.uid, a.ip, a.login_time
FROM (SELECT uid, max(login_time) login_time
FROM tb
GROUP BY uid
) b JOIN tb a ON a.uid = b.uid AND a.login_time = b.login_time;

물론 결과는 같습니다:

+------+---------------+---------------------+
| uid  | ip            | login_time          |
+------+---------------+---------------------+
| 1003 | 192.168.1.153 | 2017-01-21 19:30:51 |
| 1002 | 192.168.1.66  | 2017-01-21 19:12:32 |
| 1001 | 192.168.1.231 | 2017-01-21 19:55:34 |
+------+---------------+---------------------+

참고: 최소값을 그룹화하려면 해당 기능과 기호를 변경하면 됩니다.


위 내용은 MySQL - GROUP BY 그룹화를 통해 필드 샘플 코드 세부 정보의 최대값 가져오기의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.