[SQL] 각 그룹의 마지막 레코드를 가져 - MySQL의
SQL각 그룹의 마지막 레코드를 가져 - MySQL의
아래와 같이 데이터를 포함하는 테이블에 메시지가 있습니다 :
Id Name Other_Columns
-------------------------
1 A A_data_1
2 A A_data_2
3 A A_data_3
4 B B_data_1
5 B B_data_2
6 C C_data_1
내가 이름으로 메시지 그룹에서 쿼리를 선택 *를 실행하면, 나는 결과를 얻을 것이다 :
1 A A_data_1
4 B B_data_1
6 C C_data_1
어떤 쿼리는 다음과 같은 결과를 반환합니다?
3 A A_data_3
5 B B_data_2
6 C C_data_1
즉, 각 그룹의 마지막 레코드가 반환해야합니다.
현재, 이것은 내가 사용하는 쿼리는 다음과 같습니다
SELECT
*
FROM (SELECT
*
FROM messages
ORDER BY id DESC) AS x
GROUP BY name
그러나 이것은 매우 비효율적 보인다. 다른 방법은 같은 결과를 달성하기 위해?
해결법
-
==============================
1.MySQL의 8.0는 이제 거의 모든 인기있는 SQL 구현과 같은 기능을 윈도 지원합니다. 이 표준 문법, 우리는 가장 큰-N 당 그룹 쿼리를 작성할 수 있습니다 :
MySQL의 8.0는 이제 거의 모든 인기있는 SQL 구현과 같은 기능을 윈도 지원합니다. 이 표준 문법, 우리는 가장 큰-N 당 그룹 쿼리를 작성할 수 있습니다 :
WITH ranked_messages AS ( SELECT m.*, ROW_NUMBER() OVER (PARTITION BY name ORDER BY id DESC) AS rn FROM messages AS m ) SELECT * FROM ranked_messages WHERE rn = 1;
아래는 제가 2009 년에이 질문에 대해 쓴 원래의 대답은 :
나는 해결책이 방법을 쓰기 :
SELECT m1.* FROM messages m1 LEFT JOIN messages m2 ON (m1.name = m2.name AND m1.id < m2.id) WHERE m2.id IS NULL;
성능, 하나 개의 솔루션 또는 다른와 관련하여 데이터의 특성에 따라 더 좋을 수 있습니다. 당신은 두 쿼리를 테스트하고 데이터베이스 주어진 성능에서 더 나은 하나를 사용해야합니다 그래서.
예를 들어, 나는 StackOverflow의 당당한 데이터 덤프의 사본을 가지고있다. 나는 벤치마킹을 위해 그것을 사용합니다. 소식 테이블에 1,114,357 행이 있습니다. 이것은 나의 맥북 프로 2.40GHz에서 MySQL 5.0.75에서 실행되고 있습니다.
나는 주어진 사용자 ID (광산)에 대한 가장 최근의 게시물을 찾기 위해 쿼리를 작성할 수 있습니다.
첫 번째 하위 쿼리에서 그룹 BY와 @Eric에 의해 표시되는 기술을 사용하여 :
SELECT p1.postid FROM Posts p1 INNER JOIN (SELECT pi.owneruserid, MAX(pi.postid) AS maxpostid FROM Posts pi GROUP BY pi.owneruserid) p2 ON (p1.postid = p2.maxpostid) WHERE p1.owneruserid = 20860; 1 row in set (1 min 17.89 sec)
심지어는 분석을 16 초 동안 소요 EXPLAIN :
+----+-------------+------------+--------+----------------------------+-------------+---------+--------------+---------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+------------+--------+----------------------------+-------------+---------+--------------+---------+-------------+ | 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 76756 | | | 1 | PRIMARY | p1 | eq_ref | PRIMARY,PostId,OwnerUserId | PRIMARY | 8 | p2.maxpostid | 1 | Using where | | 2 | DERIVED | pi | index | NULL | OwnerUserId | 8 | NULL | 1151268 | Using index | +----+-------------+------------+--------+----------------------------+-------------+---------+--------------+---------+-------------+ 3 rows in set (16.09 sec)
지금 가입 LEFT 내 기술을 사용하여 동일한 쿼리 결과를 생성 :
SELECT p1.postid FROM Posts p1 LEFT JOIN posts p2 ON (p1.owneruserid = p2.owneruserid AND p1.postid < p2.postid) WHERE p2.postid IS NULL AND p1.owneruserid = 20860; 1 row in set (0.28 sec)
두 테이블은 자신의 인덱스를 사용 할 수있는 분석 프로그램을 EXPLAIN :
+----+-------------+-------+------+----------------------------+-------------+---------+-------+------+--------------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+----------------------------+-------------+---------+-------+------+--------------------------------------+ | 1 | SIMPLE | p1 | ref | OwnerUserId | OwnerUserId | 8 | const | 1384 | Using index | | 1 | SIMPLE | p2 | ref | PRIMARY,PostId,OwnerUserId | OwnerUserId | 8 | const | 1384 | Using where; Using index; Not exists | +----+-------------+-------+------+----------------------------+-------------+---------+-------+------+--------------------------------------+ 2 rows in set (0.00 sec)
여기에 내 게시물 테이블에 대한 DDL이다 :
CREATE TABLE `posts` ( `PostId` bigint(20) unsigned NOT NULL auto_increment, `PostTypeId` bigint(20) unsigned NOT NULL, `AcceptedAnswerId` bigint(20) unsigned default NULL, `ParentId` bigint(20) unsigned default NULL, `CreationDate` datetime NOT NULL, `Score` int(11) NOT NULL default '0', `ViewCount` int(11) NOT NULL default '0', `Body` text NOT NULL, `OwnerUserId` bigint(20) unsigned NOT NULL, `OwnerDisplayName` varchar(40) default NULL, `LastEditorUserId` bigint(20) unsigned default NULL, `LastEditDate` datetime default NULL, `LastActivityDate` datetime default NULL, `Title` varchar(250) NOT NULL default '', `Tags` varchar(150) NOT NULL default '', `AnswerCount` int(11) NOT NULL default '0', `CommentCount` int(11) NOT NULL default '0', `FavoriteCount` int(11) NOT NULL default '0', `ClosedDate` datetime default NULL, PRIMARY KEY (`PostId`), UNIQUE KEY `PostId` (`PostId`), KEY `PostTypeId` (`PostTypeId`), KEY `AcceptedAnswerId` (`AcceptedAnswerId`), KEY `OwnerUserId` (`OwnerUserId`), KEY `LastEditorUserId` (`LastEditorUserId`), KEY `ParentId` (`ParentId`), CONSTRAINT `posts_ibfk_1` FOREIGN KEY (`PostTypeId`) REFERENCES `posttypes` (`PostTypeId`) ) ENGINE=InnoDB;
-
==============================
2.UPD : 2017년 3월 31일, MySQL을 5.7.5이 ONLY_FULL_GROUP_BY 스위치를 만든 버전 (따라서, 쿼리 BY 비 결정적 그룹이 비활성화되었습니다) 기본적으로 사용 가능. 또한, 그들은 구현하여 GROUP 업데이트, 심지어 장애인 스위치를 더 이상 예상대로 솔루션은 작동하지 않을 수 있습니다. 하나는 확인해야합니다.
UPD : 2017년 3월 31일, MySQL을 5.7.5이 ONLY_FULL_GROUP_BY 스위치를 만든 버전 (따라서, 쿼리 BY 비 결정적 그룹이 비활성화되었습니다) 기본적으로 사용 가능. 또한, 그들은 구현하여 GROUP 업데이트, 심지어 장애인 스위치를 더 이상 예상대로 솔루션은 작동하지 않을 수 있습니다. 하나는 확인해야합니다.
작품 벌금 위 빌 Karwin의 솔루션은 그룹 내에서 항목 수는 오히려 작은 경우,하지만 그룹이 오히려 큰 경우이 솔루션은 N * N 단의 / 2 + N / 2 NULL 비교 약이 필요하기 때문에 쿼리의 성능이 나쁜됩니다.
나는 1182 개 그룹과 18,684,446 행의 InnoDB의 테이블에 내 테스트를했다. 표는 작용 성 시험 testresults 포함하고, 기본 키 (test_id, REQUEST_ID)을 갖는다. 따라서 test_id는 기이고 I는 각 test_id 대한 마지막 REQUEST_ID를 검색 하였다.
빌의 솔루션은 이미 내 델 E4310에 몇 시간 동안 실행되었으며 (따라서 EXPLAIN에서 인덱스를 사용) 커버리지 지수에서 작동에도 불구하고 끝내려고 할 때 나도 몰라.
저도 같은 생각을 기반으로하는 다른 솔루션의 몇 가지있다 :
3 가지 방법 MySQL을 사용 인덱스는 몇 가지 세부 사항을 이해할 수있는 좋은 기사입니다.
해결 방법 1
이 사람은 믿을 수 없을만큼 빠른, 내 18M + 행에 0.8에 대한 초 걸립니다 :
SELECT test_id, MAX(request_id) AS request_id FROM testresults GROUP BY test_id DESC;
당신은 ASC에 순서를 변경 하위 쿼리에 넣어, 그 열의 나머지에 가입하는 부질으로 유일한 식별자 및 사용을 반환하려면 :
SELECT test_id, request_id FROM ( SELECT test_id, MAX(request_id) AS request_id FROM testresults GROUP BY test_id DESC) as ids ORDER BY test_id;
이 사람은 내 데이터에 1, 2에 대한 초 걸립니다.
해결 방법 2
여기 내 테이블에 대한 19초 정도 걸립니다 또 다른 솔루션입니다 :
SELECT test_id, request_id FROM testresults, (SELECT @group:=NULL) as init WHERE IF(IFNULL(@group, -1)=@group:=test_id, 0, 1) ORDER BY test_id DESC, request_id DESC
그것은뿐만 아니라 내림차순으로 테스트를 반환합니다. 그것은 전체 인덱스 스캔을 수행하지만 어떻게 각 그룹에 대한 출력 N 최대 행 당신에게 아이디어를주고 여기에 있기 때문에 그것은 느린 많이 있습니다.
쿼리의 단점은 그 결과가 쿼리 캐시 캐시 할 수 없다는 것입니다.
-
==============================
3.당신은 거기 중간이기 때문에, 올바른 그룹을 반환하기 위해 서브 쿼리를 사용합니다.
당신은 거기 중간이기 때문에, 올바른 그룹을 반환하기 위해 서브 쿼리를 사용합니다.
이 시도:
select a.* from messages a inner join (select name, max(id) as maxid from messages group by name) as b on a.id = b.maxid
당신의 최대를 원하는 경우 그렇지 않은 경우 :
select a.* from messages a inner join (select name, max(other_col) as other_col from messages group by name) as b on a.name = b.name and a.other_col = b.other_col
이 방법을 사용하면 매우 느린 / 비효율적 인 경향이 귀하의 하위 쿼리에 상관 하위 쿼리 및 / 또는 주문을 피하십시오.
-
==============================
4.그럼, 각 그룹 내 마지막 게시물에 대한 ID를 얻을 WHERE X의 구조에 대한 인수로 첫 번째 쿼리의 결과를 사용하여 메시지 테이블에서 선택하는 다른 솔루션에 도착했다 :
그럼, 각 그룹 내 마지막 게시물에 대한 ID를 얻을 WHERE X의 구조에 대한 인수로 첫 번째 쿼리의 결과를 사용하여 메시지 테이블에서 선택하는 다른 솔루션에 도착했다 :
SELECT id, name, other_columns FROM messages WHERE id IN ( SELECT MAX(id) FROM messages GROUP BY name );
나는이 수행은 다른 솔루션의 일부에 비해 방법을 모른다, 그러나 3+ 백만 행 내 테이블 화려했다. (1200+ 결과 4 번째 실행)
이것은 MySQL과 SQL 서버에서 모두 작동합니다.
-
==============================
5.서브 쿼리 바이올린 링크에 의해 해결
서브 쿼리 바이올린 링크에 의해 해결
select * from messages where id in (select max(id) from messages group by Name)
해결 방법으로는 조건 바이올린 링크를 가입
select m1.* from messages m1 left outer join messages m2 on ( m1.id<m2.id and m1.name=m2.name ) where m2.id is null
이 게시물에 대한 이유는 바이올린 링크 만 제공하는 것입니다. 같은 SQL은 이미 다른 답변에서 제공됩니다.
-
==============================
6.다음과 같이 상당한 속도로 접근 방법이다.
다음과 같이 상당한 속도로 접근 방법이다.
SELECT * FROM messages a WHERE Id = (SELECT MAX(Id) FROM messages WHERE a.Name = Name)
결과
Id Name Other_Columns 3 A A_data_3 5 B B_data_2 6 C C_data_1
-
==============================
7.여기에 두 가지 제안 사항입니다. 첫째, MySQL의 지원에 ROW_NUMBER ()가, 매우 간단 경우 :
여기에 두 가지 제안 사항입니다. 첫째, MySQL의 지원에 ROW_NUMBER ()가, 매우 간단 경우 :
WITH Ranked AS ( SELECT Id, Name, OtherColumns, ROW_NUMBER() OVER ( PARTITION BY Name ORDER BY Id DESC ) AS rk FROM messages ) SELECT Id, Name, OtherColumns FROM messages WHERE rk = 1;
난 당신이 아이디 위해 마지막 말은 "마지막"에 의해 있으리라 믿고있어. 그렇지 않을 경우, 그에 따라 ROW_NUMBER () 윈도우의 ORDER BY 절을 변경합니다. ROW_NUMBER ()를 사용할 수없는 경우, 이것은 또 다른 솔루션입니다 :
그렇지 않은 경우 둘째,이 종종 진행하는 좋은 방법입니다 :
SELECT Id, Name, OtherColumns FROM messages WHERE NOT EXISTS ( SELECT * FROM messages as M2 WHERE M2.Name = messages.Name AND M2.Id > messages.Id )
더 같은 이름을 가진 이후-ID 메시지가있는 경우 즉, 메시지를 선택합니다.
-
==============================
8.아직 많은 DB 테스트 적이 없다하지만 난이 테이블을 조인보다 빠를 수 있다고 생각 :
아직 많은 DB 테스트 적이 없다하지만 난이 테이블을 조인보다 빠를 수 있다고 생각 :
SELECT *, Max(Id) FROM messages GROUP BY Name
-
==============================
9.다음 목록에서 레코드 하나를 선택하는 또 다른 의해 주문 GROUP_CONCAT를 사용하여 마지막으로 관련 기록을 얻을 수있는 방법과 SUBSTRING_INDEX입니다
다음 목록에서 레코드 하나를 선택하는 또 다른 의해 주문 GROUP_CONCAT를 사용하여 마지막으로 관련 기록을 얻을 수있는 방법과 SUBSTRING_INDEX입니다
SELECT `Id`, `Name`, SUBSTRING_INDEX( GROUP_CONCAT( `Other_Columns` ORDER BY `Id` DESC SEPARATOR '||' ), '||', 1 ) Other_Columns FROM messages GROUP BY `Name`
쿼리 의지 그룹 이름이 같은 그룹에 내가 사용한 내 경우에는 제공된 구분하여 내림차순으로 특정 그룹의 모든 Other_Columns에 참여합니다 아이디 DESC BY ORDER를 사용하여 모든 Other_Columns 위 || 이 목록을 통해 SUBSTRING_INDEX를 사용하는 최초의 하나를 선택합니다
-
==============================
10.분명히 같은 결과를 얻는 다른 많은 방법이있다, 당신의 질문은 MySQL의 각 그룹의 마지막 결과를 얻는하는 효율적인 방법이 무엇인지 것 같다. 당신은 엄청난 양의 데이터로 작업하고 MySQL의의도 최신 버전으로 이노를 사용하는 가정하는 경우 (예 : 5.7.21 및 8.0.4-RC로) 다음이 일을하는 효율적인 방법이되지 않을 수 있습니다.
분명히 같은 결과를 얻는 다른 많은 방법이있다, 당신의 질문은 MySQL의 각 그룹의 마지막 결과를 얻는하는 효율적인 방법이 무엇인지 것 같다. 당신은 엄청난 양의 데이터로 작업하고 MySQL의의도 최신 버전으로 이노를 사용하는 가정하는 경우 (예 : 5.7.21 및 8.0.4-RC로) 다음이 일을하는 효율적인 방법이되지 않을 수 있습니다.
우리는 때로는 60 개 이상의 백만 행이있는 테이블이 작업을 수행해야합니다.
이 예를 들어 나는 쿼리가 데이터의 모든 그룹에 대한 결과를 찾을 필요가 약 150 만 개 행이 데이터를 사용합니다. 우리의 실제 경우에 우리는 종종 (가설 필요가 매우 많은 데이터를 검사하지 않을) 2000에 대한 그룹에서 데이터를 다시 반환해야합니다.
나는 다음과 같은 테이블을 사용합니다 :
CREATE TABLE temperature( id INT UNSIGNED NOT NULL AUTO_INCREMENT, groupID INT UNSIGNED NOT NULL, recordedTimestamp TIMESTAMP NOT NULL, recordedValue INT NOT NULL, INDEX groupIndex(groupID, recordedTimestamp), PRIMARY KEY (id) ); CREATE TEMPORARY TABLE selected_group(id INT UNSIGNED NOT NULL, PRIMARY KEY(id));
온도 표는 150 만에 대한 임의의 기록으로 채워, 100 개 다른 그룹으로한다. selected_group는 그 100 개 그룹으로 채워집니다 (우리의 경우에 이것은 일반적으로 모든 그룹에 대한 20 % 미만이 될 것이다).
이 데이터가 랜덤으로 복수 행 동일한 recordedTimestamps을 가질 수 있다는 것을 의미한다. 우리가 원하는 것은 각 그룹의 마지막 recordedTimestamp와 그룹 ID의 순서로 선택된 모든 그룹의 목록을 얻을 수 있으며, 같은 그룹은 해당 행의 다음 마지막으로 일치 ID로 하나 이상의 일치하는 행이있는 경우.
가설 MySQL은 BY 절 특별 주문에 마지막 행에서 값을 반환 마지막 () 함수를 가지고 있다면 우리는 간단하게 할 수있는 :
SELECT last(t1.id) AS id, t1.groupID, last(t1.recordedTimestamp) AS recordedTimestamp, last(t1.recordedValue) AS recordedValue FROM selected_group g INNER JOIN temperature t1 ON t1.groupID = g.id ORDER BY t1.recordedTimestamp, t1.id GROUP BY t1.groupID;
이는 단지이 기능에 의해 정상 군을 사용하지 않기 때문에이 경우에는 몇 백 개 행을 검사해야합니다. 이 0 초 단위로 실행하고, 따라서 고효율 될 것이다. 일반적으로 MySQL의에서 우리가 다음이 그룹을 주문 될 수는 GROUP BY 후 있다면 그러나 조항으로이 순서는, 마지막 () 함수의 순서를 결정하는 데 사용되는 GROUP BY 절 다음 ORDER BY 절을 볼 것입니다 참고. BY 절에는 GROUP가없는 경우, 마지막 값이 반환 된 모든 행에서 동일합니다.
그러나 MySQL은이 있고 이들 중 어느 것도 효율적인없는 증명 않는 어떤 다른 생각에이 그렇게하자 모습을 가지고 있지 않습니다.
예 1
SELECT t1.id, t1.groupID, t1.recordedTimestamp, t1.recordedValue FROM selected_group g INNER JOIN temperature t1 ON t1.id = ( SELECT t2.id FROM temperature t2 WHERE t2.groupID = g.id ORDER BY t2.recordedTimestamp DESC, t2.id DESC LIMIT 1 );
이 3,009,254 행을 검사하고 8.0.4-RC에 약간 이상 5.7.21에 ~ 0.859 초 걸렸 및
예 2
SELECT t1.id, t1.groupID, t1.recordedTimestamp, t1.recordedValue FROM temperature t1 INNER JOIN ( SELECT max(t2.id) AS id FROM temperature t2 INNER JOIN ( SELECT t3.groupID, max(t3.recordedTimestamp) AS recordedTimestamp FROM selected_group g INNER JOIN temperature t3 ON t3.groupID = g.id GROUP BY t3.groupID ) t4 ON t4.groupID = t2.groupID AND t4.recordedTimestamp = t2.recordedTimestamp GROUP BY t2.groupID ) t5 ON t5.id = t1.id;
이 1,505,331 행을 검사하고 8.0.4-RC에 약간 이상 5.7.21에 ~ 1.25 초 걸렸 및
예 3
SELECT t1.id, t1.groupID, t1.recordedTimestamp, t1.recordedValue FROM temperature t1 WHERE t1.id IN ( SELECT max(t2.id) AS id FROM temperature t2 INNER JOIN ( SELECT t3.groupID, max(t3.recordedTimestamp) AS recordedTimestamp FROM selected_group g INNER JOIN temperature t3 ON t3.groupID = g.id GROUP BY t3.groupID ) t4 ON t4.groupID = t2.groupID AND t4.recordedTimestamp = t2.recordedTimestamp GROUP BY t2.groupID ) ORDER BY t1.groupID;
이 3,009,685 행을 검사하고 8.0.4-RC에 약간 이상 5.7.21에 ~ 1.95 초 걸렸 및
예 4
SELECT t1.id, t1.groupID, t1.recordedTimestamp, t1.recordedValue FROM selected_group g INNER JOIN temperature t1 ON t1.id = ( SELECT max(t2.id) FROM temperature t2 WHERE t2.groupID = g.id AND t2.recordedTimestamp = ( SELECT max(t3.recordedTimestamp) FROM temperature t3 WHERE t3.groupID = g.id ) );
이 6,137,810 행을 검사하고 8.0.4-RC에 약간 이상 5.7.21에 ~ 2.2 초가 소요 및
예 5
SELECT t1.id, t1.groupID, t1.recordedTimestamp, t1.recordedValue FROM ( SELECT t2.id, t2.groupID, t2.recordedTimestamp, t2.recordedValue, row_number() OVER ( PARTITION BY t2.groupID ORDER BY t2.recordedTimestamp DESC, t2.id DESC ) AS rowNumber FROM selected_group g INNER JOIN temperature t2 ON t2.groupID = g.id ) t1 WHERE t1.rowNumber = 1;
이 6,017,808 행을 검사하고 8.0.4-RC에 ~ 4.2 초 걸렸습니다
예 6
SELECT t1.id, t1.groupID, t1.recordedTimestamp, t1.recordedValue FROM ( SELECT last_value(t2.id) OVER w AS id, t2.groupID, last_value(t2.recordedTimestamp) OVER w AS recordedTimestamp, last_value(t2.recordedValue) OVER w AS recordedValue FROM selected_group g INNER JOIN temperature t2 ON t2.groupID = g.id WINDOW w AS ( PARTITION BY t2.groupID ORDER BY t2.recordedTimestamp, t2.id RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) ) t1 GROUP BY t1.groupID;
이 6,017,908 행을 검사하고 8.0.4-RC에 ~ 17.5 초 걸렸습니다
예 7
SELECT t1.id, t1.groupID, t1.recordedTimestamp, t1.recordedValue FROM selected_group g INNER JOIN temperature t1 ON t1.groupID = g.id LEFT JOIN temperature t2 ON t2.groupID = g.id AND ( t2.recordedTimestamp > t1.recordedTimestamp OR (t2.recordedTimestamp = t1.recordedTimestamp AND t2.id > t1.id) ) WHERE t2.id IS NULL ORDER BY t1.groupID;
내가 죽일했다, 그래서이 사람은 영원히 가고 있었다.
-
==============================
11.우리는 당신이 기록함으로써 그룹의 마지막 레코드를 받고에서 MySQL을 사용하는 방법을 살펴볼 것이다. 예를 들어, 당신은 게시물의 결과 집합이있는 경우.
우리는 당신이 기록함으로써 그룹의 마지막 레코드를 받고에서 MySQL을 사용하는 방법을 살펴볼 것이다. 예를 들어, 당신은 게시물의 결과 집합이있는 경우.
1 개 1 제목 1
2 1 제목 2
3 1 제목 3
4 2 제목 4
5 2 제목 5
6 세 제목 6
나는 제목 3 제목 5 제목 6. 당신은 MySQL의 그룹으로 키보드를 사용하는 카테고리별로 게시물을 얻으려면 각각의 카테고리에서 마지막 게시물을 얻을 수 있어야합니다.
CATEGORY_ID 게시물 그룹 SELECT * FROM
이 쿼리가에서 그러나 결과는 우리가 다시 얻을.
1 개 1 제목 1
4 2 제목 4
6 세 제목 6
에 의해 그룹은 항상 결과 세트에 그룹의 첫 번째 레코드를 반환합니다.
SELECT ID, CATEGORY_ID, POST_TITLE 게시물 FROM WHERE 아이디 IN ( SELECT MAX (ID) 게시물 FROM GROUP BY의 CATEGORY_ID );
이것은 각 그룹에서 가장 높은 ID로 게시물을 반환합니다.
3 1 제목 3
5 2 제목 5
6 세 제목 6
참조 여기를 클릭하세요
-
==============================
12.
SELECT column1, column2 FROM table_name WHERE id IN (SELECT MAX(id) FROM table_name GROUP BY column1) ORDER BY column1 ;
-
==============================
13.여기 내 솔루션입니다 :
여기 내 솔루션입니다 :
SELECT DISTINCT NAME, MAX(MESSAGES) OVER(PARTITION BY NAME) MESSAGES FROM MESSAGE;
-
==============================
14.이 시도:
이 시도:
SELECT jos_categories.title AS name, joined .catid, joined .title, joined .introtext FROM jos_categories INNER JOIN (SELECT * FROM (SELECT `title`, catid, `created`, introtext FROM `jos_content` WHERE `sectionid` = 6 ORDER BY `id` DESC) AS yes GROUP BY `yes`.`catid` DESC ORDER BY `yes`.`created` DESC) AS joined ON( joined.catid = jos_categories.id )
-
==============================
15.쿼리는 다음과 같이 읽어야 기본 키에 대한 최신 기록 기초를 가져 오기 위해 다음 자동 증가 기본 키 안녕 @Vijay 데브 테이블 메시지가 이드가 포함되어있는 경우 :
쿼리는 다음과 같이 읽어야 기본 키에 대한 최신 기록 기초를 가져 오기 위해 다음 자동 증가 기본 키 안녕 @Vijay 데브 테이블 메시지가 이드가 포함되어있는 경우 :
SELECT m1.* FROM messages m1 INNER JOIN (SELECT max(Id) as lastmsgId FROM messages GROUP BY Name) m2 ON m1.Id=m2.lastmsgId
-
==============================
16.당신은 여기뿐만 아니라에서 볼 수 있습니다.
당신은 여기뿐만 아니라에서 볼 수 있습니다.
http://sqlfiddle.com/#!9/ef42b/9
FIRST 솔루션
SELECT d1.ID,Name,City FROM Demo_User d1 INNER JOIN (SELECT MAX(ID) AS ID FROM Demo_User GROUP By NAME) AS P ON (d1.ID=P.ID);
SECOND SOLUTION
SELECT * FROM (SELECT * FROM Demo_User ORDER BY ID DESC) AS T GROUP BY NAME ;
-
==============================
17.우리는 테이블에서 삭제 중복이 방법을 사용할 수있는 방법이 있습니까? 결과 세트는 우리가 결과 집합에 모든 기록을 삭제할 수 있습니다, 그래서 만약 우리가 효과적으로에는 중복이없는 것, 기본적으로 독특한 기록의 모음입니다? 나는이 시도하지만, MySQL의는 1093 오류를했다.
우리는 테이블에서 삭제 중복이 방법을 사용할 수있는 방법이 있습니까? 결과 세트는 우리가 결과 집합에 모든 기록을 삭제할 수 있습니다, 그래서 만약 우리가 효과적으로에는 중복이없는 것, 기본적으로 독특한 기록의 모음입니다? 나는이 시도하지만, MySQL의는 1093 오류를했다.
DELETE FROM messages WHERE id NOT IN (SELECT m1.id FROM messages m1 LEFT JOIN messages m2 ON (m1.name = m2.name AND m1.id < m2.id) WHERE m2.id IS NULL)
어쩌면 임시 변수에 출력을 저장 한 후 NOT IN (임시 변수)에서 삭제하는 방법이 있나요? 매우 유용한 솔루션 @ 빌 감사합니다.
편집 : 내가 해결책을 찾은 것 같아요 :
DROP TABLE IF EXISTS UniqueIDs; CREATE Temporary table UniqueIDs (id Int(11)); INSERT INTO UniqueIDs (SELECT T1.ID FROM Table T1 LEFT JOIN Table T2 ON (T1.Field1 = T2.Field1 AND T1.Field2 = T2.Field2 #Comparison Fields AND T1.ID < T2.ID) WHERE T2.ID IS NULL); DELETE FROM Table WHERE id NOT IN (SELECT ID FROM UniqueIDs);
-
==============================
18.쿼리 아래는 귀하의 질문에 따라 벌금을 작동합니다.
쿼리 아래는 귀하의 질문에 따라 벌금을 작동합니다.
SELECT M1.* FROM MESSAGES M1, ( SELECT SUBSTR(Others_data,1,2),MAX(Others_data) AS Max_Others_data FROM MESSAGES GROUP BY 1 ) M2 WHERE M1.Others_data = M2.Max_Others_data ORDER BY Others_data;
-
==============================
19.각 이름의 마지막 행을 원하는 경우에, 당신은 내림차순으로 ID를 기준으로 각 행의 이름으로 그룹 순서에 행 번호를 제공 할 수 있습니다.
각 이름의 마지막 행을 원하는 경우에, 당신은 내림차순으로 ID를 기준으로 각 행의 이름으로 그룹 순서에 행 번호를 제공 할 수 있습니다.
질문
SELECT t1.Id, t1.Name, t1.Other_Columns FROM ( SELECT Id, Name, Other_Columns, ( CASE Name WHEN @curA THEN @curRow := @curRow + 1 ELSE @curRow := 1 AND @curA := Name END ) + 1 AS rn FROM messages t, (SELECT @curRow := 0, @curA := '') r ORDER BY Name,Id DESC )t1 WHERE t1.rn = 1 ORDER BY t1.Id;
-
==============================
20.
SELECT * FROM table_name WHERE primary_key IN (SELECT MAX(primary_key) FROM table_name GROUP BY column_name )
-
==============================
21.**
**
안녕하세요, 쿼리는 도움이 될 수 있습니다 :
**
SELECT * FROM message WHERE `Id` IN ( SELECT MAX(`Id`) FROM message GROUP BY `Name` ) ORDER BY `Id` DESC
-
==============================
22.이건 어때:
이건 어때:
SELECT DISTINCT ON (name) * FROM messages ORDER BY name, id DESC;
내가하고 1M 기록 테이블에 (힘든 PostgreSQL을에) 유사한 문제가 있었다. LEFT 함께 하나에 의해 생성 된 44S 조인 대이 용액 1.7s 걸린다. 내 경우에는 내가 0.2 초에 의해 더 나은 성능의 결과로 NULL 값에 대한 사용자 이름 필드의 corrispondant을 필터링 할 수 있었다
-
==============================
23.성능이 우려 정말 경우에 당신은 형 BIT의 IsLastInGroup라는 테이블에 새 열을 도입 할 수 있습니다.
성능이 우려 정말 경우에 당신은 형 BIT의 IsLastInGroup라는 테이블에 새 열을 도입 할 수 있습니다.
마지막 인 열을 true로 설정하고 삭제 모든 행의 삽입 / 업데이트 / 그것을 유지. 쓰기가 느려집니다,하지만 당신은 읽기에 혜택을 얻을 것입니다. 그것은 당신의 사용 사례에 따라 달라집니다 그리고 당신이있는 거 읽기에 초점을 맞춘 경우에만하는 것이 좋습니다.
쿼리에 모양을 따라서 :
SELECT * FROM Messages WHERE IsLastInGroup = 1
-
==============================
24.
select * from messages group by name desc
-
==============================
25.당신이 할 수 계산에 의해 그룹과도 같은 그룹의 마지막 항목을 얻을 :
당신이 할 수 계산에 의해 그룹과도 같은 그룹의 마지막 항목을 얻을 :
SELECT user, COUNT(user) AS count, MAX(id) as last FROM request GROUP BY user
-
==============================
26.오라클 쿼리 캔의 도움 아래 희망 :
오라클 쿼리 캔의 도움 아래 희망 :
WITH Temp_table AS ( Select id, name, othercolumns, ROW_NUMBER() over (PARTITION BY name ORDER BY ID desc)as rank from messages ) Select id, name,othercolumns from Temp_table where rank=1
-
==============================
27.또 다른 방법 :
또 다른 방법 :
(1 개 프로그램 속성) 각 프로그램 내에서 최대 m2의 가격으로 부동산 찾기 :
select * from properties p join ( select max(m2_price) as max_price from properties group by program_id ) p2 on (p.program_id = p2.program_id) having p.m2_price = max_price
from https://stackoverflow.com/questions/1313120/retrieving-the-last-record-in-each-group-mysql by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] SQL 서버 동적 PIVOT 쿼리? (0) | 2020.03.04 |
---|---|
[SQL] 어떻게 SQL 서버에서 하나의 텍스트 문자열에 여러 행의 텍스트를 연결하는? (0) | 2020.03.04 |
[SQL] 각 GROUP BY 그룹에서 첫 번째 행을 선택? (0) | 2020.03.04 |
[SQL] 2005 마이크로 소프트 SQL 서버에서 GROUP_CONCAT MySQL의 기능을 시뮬레이션? (0) | 2020.03.04 |
[SQL] 열에 최대 값 행만에서 SQL [중복] (0) | 2020.03.04 |