MySQL의 각 그룹에 대한 첫 번째 행을 선택하는 방법은 무엇입니까?
C #에서는 다음과 같습니다.
table
.GroupBy(row => row.SomeColumn)
.Select(group => group
.OrderBy(row => row.AnotherColumn)
.First()
)
Linq-To-Sql은이를 다음 T-SQL 코드로 변환합니다.
SELECT [t3].[AnotherColumn], [t3].[SomeColumn]
FROM (
SELECT [t0].[SomeColumn]
FROM [Table] AS [t0]
GROUP BY [t0].[SomeColumn]
) AS [t1]
OUTER APPLY (
SELECT TOP (1) [t2].[AnotherColumn], [t2].[SomeColumn]
FROM [Table] AS [t2]
WHERE (([t1].[SomeColumn] IS NULL) AND ([t2].[SomeColumn] IS NULL))
OR (([t1].[SomeColumn] IS NOT NULL) AND ([t2].[SomeColumn] IS NOT NULL)
AND ([t1].[SomeColumn] = [t2].[SomeColumn]))
ORDER BY [t2].[AnotherColumn]
) AS [t3]
ORDER BY [t3].[AnotherColumn]
그러나 MySQL과 호환되지 않습니다.
나는 C #을 모르고 주어진 쿼리를 이해하지 못했기 때문에 귀하의 게시물 제목에만 내 대답을 기반으로했습니다. 그러나 MySQL에서는 하위 선택을 시도하는 것이 좋습니다. 먼저 관심있는 열의 기본 키 집합을 가져온 다음 해당 행에서 데이터를 선택합니다.
SELECT somecolumn, anothercolumn
FROM sometable
WHERE id IN (
SELECT min(id)
FROM sometable
GROUP BY somecolumn
);
내가 쓸 때
SELECT AnotherColumn
FROM Table
GROUP BY SomeColumn
;
효과가있다. 다른 RDBMS의 IIRC는 그룹화 키에 속하지 않는 열이 어떤 종류의 집계없이 참조되기 때문에 불가능합니다.
이 "특이 함"은 내가 원하는 것과 매우 밀접하게 작용합니다. 그래서 원하는 결과를 얻기 위해 사용했습니다.
SELECT * FROM
(
SELECT * FROM `table`
ORDER BY AnotherColumn
) t1
GROUP BY SomeColumn
;
시도 할 수있는 또 다른 방법이 있습니다. ID 필드가 필요하지 않습니다.
select some_column, min(another_column)
from i_have_a_table
group by some_column
여전히 기본 키를 추가해야한다는 lfagundes에 동의합니다 ..
또한 이렇게하면 다른 값이 결과로 나오는 some_colum, another_column 쌍과 동일한 행을 (쉽게) 얻을 수 없다는 점에 유의하십시오! 그렇게하려면 lfagundes apprach와 PK가 필요합니다!
원하는 AnotherColumn의 값을 얻으려면 일부 집계 함수를 사용해야합니다. 즉, SomeColumn의 각 값 (숫자 또는 사전)에 대해 AnotherColumn의 가장 낮은 값을 원하는 경우 다음을 사용할 수 있습니다.
SELECT SomeColumn, MIN(AnotherColumn)
FROM YourTable
GROUP BY SomeColumn
도움이되는 몇 가지 링크 :
http://dev.mysql.com/doc/refman/5.1/en/group-by-functions.html
http://www.oreillynet.com/databases/blog/2007/05/debunking_group_by_myths.html
MySQL 5.7.5 이상은 기능 의존성 감지를 구현합니다. ONLY_FULL_GROUP_BY SQL 모드가 활성화 된 경우 (기본 설정) MySQL은 선택 목록, HAVING 조건 또는 ORDER BY 목록이 GROUP BY 절에 이름이 지정되지 않았거나 기능적으로 종속되지 않은 집계되지 않은 열을 참조하는 쿼리를 거부합니다. .
이것은 @Jader Dias의 솔루션이 모든 곳에서 작동하지 않는다는 것을 의미합니다.
ONLY_FULL_GROUP_BY
이 활성화 되었을 때 작동하는 솔루션은 다음과 같습니다 .
SET @row := NULL;
SELECT
SomeColumn,
AnotherColumn
FROM (
SELECT
CASE @id <=> SomeColumn AND @row IS NOT NULL
WHEN TRUE THEN @row := @row+1
ELSE @row := 0
END AS rownum,
@id := SomeColumn AS SomeColumn,
AnotherColumn
FROM
SomeTable
ORDER BY
SomeColumn, -AnotherColumn DESC
) _values
WHERE rownum = 0
ORDER BY SomeColumn;
대답 중 다음과 같은 해결책을 보지 못했기 때문에 거기에 넣을 것이라고 생각했습니다.
문제는로 AnotherColumn
그룹화 된 모든 그룹에서 정렬 될 때 첫 번째 행인 행을 선택 하는 것 SomeColumn
입니다.
The following solution will do this in MySQL. id
has to be a unique column which must not hold values containing -
(which I use as a separator).
select t1.*
from mytable t1
inner join (
select SUBSTRING_INDEX(
GROUP_CONCAT(t3.id ORDER BY t3.AnotherColumn DESC SEPARATOR '-'),
'-',
1
) as id
from mytable t3
group by t3.SomeColumn
) t2 on t2.id = t1.id
-- Where
SUBSTRING_INDEX(GROUP_CONCAT(id order by AnotherColumn desc separator '-'), '-', 1)
-- can be seen as:
FIRST(id order by AnotherColumn desc)
-- For completeness sake:
SUBSTRING_INDEX(GROUP_CONCAT(id order by AnotherColumn desc separator '-'), '-', -1)
-- would then be seen as:
LAST(id order by AnotherColumn desc)
There is a feature request for FIRST()
and LAST()
in the MySQL bug tracker, but it was closed many years back.
Yet another way to do it (without the primary key) would be using the JSON functions:
select somecolumn, json_unquote( json_extract(json_arrayagg(othercolumn), "$[0]") )
from sometable group by somecolumn
or pre 5.7.22
select somecolumn,
json_unquote(
json_extract(
concat('["', group_concat(othercolumn separator '","') ,'"]')
,"$[0]" )
)
from sometable group by somecolumn
Ordering (or filtering) can be done before grouping:
select somecolumn, json_unquote( json_extract(json_arrayagg(othercolumn), "$[0]") )
from (select * from sometable order by othercolumn) as t group by somecolumn
... or after grouping (of course):
select somecolumn, json_unquote( json_extract(json_arrayagg(othercolumn), "$[0]") ) as other
from sometable group by somecolumn order by other
Admittedly, it's rather convoluted and performance is probably not great (didn't test it on large data, works well on my limited data sets).
SELECT
t1.*
FROM
table_name AS t1
LEFT JOIN table_name AS t2 ON (
t2.group_by_column = t1.group_by_column
-- group_by_column is the column you would use in the GROUP BY statement
AND
t2.order_by_column < t1.order_by_column
-- order_by_column is column you would use in the ORDER BY statement
-- usually is the autoincremented key column
)
WHERE
t2.group_by_column IS NULL;
With MySQL v8+ you could use window functions
Yet another way to do it
Select max from group that works in views
SELECT * FROM action a
WHERE NOT EXISTS (
SELECT 1 FROM action a2
WHERE a2.user_id = a.user_id
AND a2.action_date > a.action_date
AND a2.action_type = a.action_type
)
AND a.action_type = "CF"
How about this:
SELECT SUBSTRING_INDEX(
MIN(CONCAT(OrderColumn, '|', IFNULL(TargetColumn, ''))
), '|', -1) as TargetColumn
FROM table
GROUP BY GroupColumn
Why not use MySQL LIMIT keyword?
SELECT [t2].[AnotherColumn], [t2].[SomeColumn]
FROM [Table] AS [t2]
WHERE (([t1].[SomeColumn] IS NULL) AND ([t2].[SomeColumn] IS NULL))
OR (([t1].[SomeColumn] IS NOT NULL) AND ([t2].[SomeColumn] IS NOT NULL)
AND ([t1].[SomeColumn] = [t2].[SomeColumn]))
ORDER BY [t2].[AnotherColumn]
LIMIT 1
ReferenceURL : https://stackoverflow.com/questions/2739474/how-to-select-the-first-row-for-each-group-in-mysql
'Program Tip' 카테고리의 다른 글
Cloud Functions와 Firebase Functions의 차이점은 무엇인가요? (0) | 2020.12.15 |
---|---|
axios로 기본 인증을 보내는 방법 (0) | 2020.12.15 |
반복기를 사용하여 std :: map의 요소를 어떻게 삭제할 수 있습니까? (0) | 2020.12.15 |
JDBC에서 트랜잭션을 시작하는 방법은 무엇입니까? (0) | 2020.12.15 |
Visual Studio 2010-XAML 편집기가 매우 느림 (0) | 2020.12.15 |