MySQL - GROUP BY 샘플 코드 세부 정보를 그룹화하여 최대 필드 값 얻기:
사용자 로그인 기록 정보를 쿼리해야 하는 비즈니스 시나리오가 있고 테이블 구조가 있다고 가정합니다.
1 2 3 4 5 6 7 8 | 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`)
);
|
로그인 후 복사
추가 테스트 데이터:
1 2 3 4 5 6 7 | 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/>
1 2 3 4 5 6 7 8 9 10 11 | +
| 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/>
1 2 3 | SELECT uid, max (login_time)
FROM tb
GROUP BY uid;
|
로그인 후 복사
1 2 3 4 5 6 7 | +
| 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/>
1 2 3 4 5 | SELECT uid, ip, max (login_time)
FROM tb
GROUP BY uid;
|
로그인 후 복사
이런 문장은 SQL 표준은 아니지만 MySQL 데이터베이스에서는 실행은 성공했지만 반환값은 알 수 없다 <br/> (sql_mode가_full_group_by로만 켜져 있으면 실행이 성공하지 못한다.)
아마도 ip 필드는 uid 그룹 이전의 첫 번째 필드를 차지할 것입니다. row의 값은 분명히 필수 정보가 아닙니다 <br/>Writing 1<br/>Write a subquery: <br/>
1 2 3 4 5 6 | 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/>
1 2 3 4 5 6 | 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/>
1 2 3 4 5 6 | +
| 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/>
1 2 3 4 5 6 | +
| 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/>
1 2 3 4 5 | 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/>
1 2 3 4 5 6 7 | +
| 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!