원글 

mariadb.com/kb/en/why-is-order-by-in-a-from-subquery-ignored/

 

Why is ORDER BY in a FROM Subquery Ignored?

Query with ORDER BY in a FROM subquery produces an unordered result.

mariadb.com

찾아본 이유 

mariaDB에서 mysql과 동일한 문법과 테이블 규칙을 가지기 때문에 많이 사용된다. 

그 중 각 그룹 별 최초 혹은 마지막 데이터를 조회할 때 자주 사용되는 쿼리가 있다. 

select * 

from 

(

    select * 

    from table

    order by column_1

) as alias_table

group by column_2 

이런 식으로 정렬한 후 그룹화를 시켜서 각 그룹 컬럼 별 최신 데이터를 뽑는 쿼리를 실무나 개인 개발을 할 때 자주 사용 했었는데, 최근에 mariaDB 최신 버전을 깔고 쓰니까 기존 방식대로 작동하지 않는 것을 발견했다. 

뭐여? 하고 찾아보니 이젠 안된다고 한다. 아래 번역한 내용을 보자.(물론 원본이 더 좋다. 글도 짧은데)

 

[번역]FROM 절의 서브 쿼리 내에 있는 ORDER BY 절이 왜 무시되는가?

 

FROM절 서브쿼리에 있는 ORDER BY가 사용된 쿼리가 정렬되지 않은 결과를 제공한다. 하단이 예시 쿼리이다.

예시) SELECT field1, field2 FROM ( SELECT field1, field2 FROM table1 ORDER BY field2 ) alias

위 쿼리가 무조건 field2 컬럼으로 정렬되지 않은 결과를 반환한다.

위 쿼리가 꼭 filed2 컬럼을 기준으로 정렬된 결과를 반환하는 것은 아니다.  버그가 아니란 것이다. 

 

테이블(과 FROM 절 내의 서브쿼리)는 SQL 표준에 따라 비정렬된 행들의 집합이다. 테이블의 행들은 어떤 특정 순서에 맞춰서 나오지 않는다. 옵티마이저(최적화 툴)가 당신이 특정시킨 ORDER BY절을 무시할 수 있는 이유다. 사실, SQL 표준은 이 서브쿼리에서 ORDER BY가 적용되는 것을 허락하지도 않는다.(ORDER BY ... LIMIT ... 는 순서뿐만 아니라 '행들의 집합'인 쿼리의 결과를 바꾸기 때문에 허가하고 있다.)

 

당신은 '특정되지 않고 규명되지 않은 순서의 행들의 집합'으로서 FROM절에서 서브쿼리를 사용해야 하고, ORDER BY를 최상위 레벨의 SELECT문에서 사용해야 한다. 

 

내 생각

사실 이상한 현상은 아니다.

 

처음 이런 방식의 쿼리를 사용했을 때에도, GROUP BY를 할 때 ORDER BY의 순서가 지켜진다는 것이 RDB의 규칙 - [테이블의 데이터에는 순서가 없다] - 에 어울리지 않다고는 생각을 했었다. 심지어 쿼리 작성/실행 순서도 group by -> order by 순서이기 때문에 그룹화가 된 후에 정렬이 되는데 그룹화되기 전의 결과를 건드린다는 것 자체가 이상한 것이다. 

 

잘 돌아가니까 이 방식을 많이 애용해왔지만, 머릿속으로는 왜 될까 하면서도 돌아가니까 쓰던 걸 이젠 합당하게 못쓰게 되었으니, 매우 불편해졌다(이런 젠장!). 

 

현재의 해결책은 위 링크 혹은 번역에서 제시된 것과 같이 내부 서브쿼리에서 [ORDER BY ... LIMIT ...] 를 사용하여 쿼리의 결과 자체가 고정되도록 유도하면 원하던 결과를 낼 수 있다. LIMIT 값 조절을 위해 LIMIT에 필요 이상의 값을 할당하거나 동적 값을 유도해야 하겠지만 현재로서는 어쩔 수 없어 보인다. 

 

 

 

+ Recent posts