MySQL-그룹이 반환하는 행 제어
다음과 같은 데이터베이스 테이블이 있습니다.
id version_id field1 field2
1 1 texta text1
1 2 textb text2
2 1 textc text3
2 2 textd text4
2 3 texte text5
해결하지 않았다면 여러 버전의 행과 일부 텍스트 데이터가 포함됩니다.
나는 그것을 쿼리하고 각 ID에 대해 가장 높은 번호를 가진 버전을 반환하고 싶습니다. (따라서 위의 두 번째 및 마지막 행만).
version_id DESC로 주문하는 동안 group by를 사용해 보았지만 그룹화 된 후에 주문하는 것 같아서 작동하지 않습니다.
누구나 아이디어가 있습니까? 할 수 없다고 믿을 수가 없어!
최신 정보:
이것은 작동하지만 하위 쿼리를 사용합니다.
SELECT *
FROM (SELECT * FROM table ORDER BY version_id DESC) t1
GROUP BY t1.id
열의 그룹 별 최대 값 선택이라고합니다. 다음은 mysql에 대한 몇 가지 다른 접근 방식입니다.
방법은 다음과 같습니다.
SELECT *
FROM (SELECT id, max(version_id) as version_id FROM table GROUP BY id) t1
INNER JOIN table t2 on t2.id=t1.id and t1.version_id=t2.version_id
mysql이 서브 쿼리를 위해 메모리에 임시 테이블을 생성하지만 이것은 비교적 효율적입니다. 이 테이블에 대한 (id, version_id)에 대한 인덱스가 이미 있다고 가정합니다.
이러한 유형의 문제에 대해 하위 쿼리를 사용해야하는 것은 SQL의 결함입니다 ( 세미 조인 은 또 다른 예입니다).
하위 쿼리는 mysql에서 잘 최적화되지 않지만 상관 관계가없는 하위 쿼리는 메모리가 아닌 디스크에 기록 될 정도로 크지 않은 한 그렇게 나쁘지 않습니다. 이 쿼리에 int가 두 개뿐이라는 점을 감안할 때 하위 쿼리는 발생하기 훨씬 전에 수백만 행이 될 수 있지만 첫 번째 쿼리의 select * 하위 쿼리는이 문제를 훨씬 빨리 겪을 수 있습니다.
나는 이것이 그것을 할 것이라고 생각하지만 그것이 최고인지 빠른지 확실하지 않습니다.
SELECT * FROM table
WHERE (id, version_id) IN
(SELECT id, MAX(version_id) FROM table GROUP BY id)
SELECT id, version_id, field1, field2
FROM (
SELECT @prev = id AS st, (@prev := id), m.*
FROM (
(SELECT @prev := NULL) p,
(
SELECT *
FROM mytable
ORDER BY
id DESC, version_id DESC
) m
) m2
WHERE NOT IFNULL(st, FALSE);
하위 쿼리 없음, 하나가있는 UNIQUE INDEX ON MYTABLE (id, version_id)
경우 하나 전달 (내 생각에)
나는 일반적으로 하위 쿼리를 사용합니다.
select id, version_id, field1, field2 from datatable as dt where id = (select id from datatable where id = dt.id order by version_id desc limit 1)
이것은 의사 코드이지만 이와 같은 것이 잘 작동합니다.
select *
from table
inner join
(
select id , max(version_id) maxVersion
from table
) dvtbl ON id = dvtbl.id && versionid = dvtbl.maxVersion
이 쿼리는 다음을 기준으로 그룹없이 작업을 수행합니다.
SELECT * FROM table AS t
LEFT JOIN table AS t2
ON t.id=t2.id
AND t.version_id < t2.version_id
WHERE t2.id IS NULL
임시 테이블이 필요하지 않습니다.
더 많은 제어를 제공하는 분석 기능도 항상 사용할 수 있습니다.
select tmp.* from ( select id,version_id,field1,field2, rank() over(partition by id order by version_id desc ) as rnk from table) tmp where tmp.rnk=1
데이터 유형에 따라 rank () 함수에 문제가있는 경우 row_number () 또는 density_rank () 중에서 선택할 수도 있습니다.
나는 이것이 당신이 원하는 것이라고 생각합니다.
select id, max(v_id), field1, field2 from table group by id
내가 얻은 결과는
1, 2, textb, text2
2, 3, texte, text5
Edit: I recreated the table and insert the same data with the id an version_id being a compound primary key. This gave the answer I provided earlier. It was also in MySQL.
not tested it but something like this might work:
SELECT * FROM table GROUP BY id ORDER BY MAX(version_id) DESC
ReferenceURL : https://stackoverflow.com/questions/537223/mysql-control-which-row-is-returned-by-a-group-by
'IT story' 카테고리의 다른 글
사용자 정의 키보드를 만드는 방법 (0) | 2020.12.31 |
---|---|
HTML5 데이터 목록 옵션에 CSS 스타일을 적용하는 방법이 있습니까? (0) | 2020.12.31 |
Java에서 데스크탑 경로를 얻는 방법 (0) | 2020.12.31 |
gc ()가 메모리를 해제하지 않는 이유는 무엇입니까? (0) | 2020.12.31 |
Spring MVC-@RequestBody와 @RequestParam을 함께 사용할 수없는 이유 (0) | 2020.12.31 |