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

黄舟
풀어 주다: 2018-05-15 14:14:58
원래의
3263명이 탐색했습니다.

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';
로그인 후 복사

테이블 데이터: <br/>

+----+------+---------------+---------------------+
| 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 |
+----+------+---------------+---------------------+
로그인 후 복사

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

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을 사용하여 다음과 같이 작성할 수 없습니다. <br/>

-- 错误写法
SELECT uid, ip, max(login_time)
FROM tb
GROUP BY uid;
-- 错误写法
로그인 후 복사

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

<br/>
로그인 후 복사

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

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<br/> 아니면 글을 바꾸세요: <br/>

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);
로그인 후 복사

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

+----+--------------------+-------+------+---------------+------+---------+------+------+-------------+
| 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: <br/>

+----+--------------------+-------+------+---------------+------+---------+------------+------+-------------+
| 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<br/>조인으로 직접 변경하면 성능이 더 좋아질 것입니다: <br/>

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;
로그인 후 복사

물론 결과는 같습니다: <br/>

+------+---------------+---------------------+
| 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 이슈
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!