문제

전자 메일 테이블에서 많은 행을 선택하고 From Sender로 그룹화 할 수 있기를 원합니다. 내 쿼리는 다음과 같습니다.

SELECT 
    `timestamp`, `fromEmail`, `subject`
FROM `incomingEmails` 
GROUP BY LOWER(`fromEmail`) 
ORDER BY `timestamp` DESC

쿼리는 거의 원하는대로 작동합니다. 이메일로 그룹화 된 레코드를 선택합니다. 문제는 주제와 타임 스탬프가 특정 이메일 주소에 대한 최신 레코드에 해당하지 않는다는 것입니다.

예를 들어, 반환 될 수 있습니다.

fromEmail: john@example.com, subject: hello
fromEmail: mark@example.com, subject: welcome

데이터베이스의 레코드가 다음과 같은 경우

fromEmail: john@example.com, subject: hello
fromEmail: john@example.com, subject: programming question
fromEmail: mark@example.com, subject: welcome

"프로그래밍 질문"주제가 가장 최근 인 경우 이메일을 그룹화 할 때 MySQL이 해당 레코드를 선택하도록하려면 어떻게해야합니까?

도움이 되었습니까?

해결책

간단한 솔루션은 쿼리를 주문 문으로 하위 선택으로 래핑하는 것입니다. 첫 번째 그리고 그룹을 신청합니다 나중에:

SELECT * FROM ( 
    SELECT `timestamp`, `fromEmail`, `subject`
    FROM `incomingEmails` 
    ORDER BY `timestamp` DESC
) AS tmp_table GROUP BY LOWER(`fromEmail`)

이것은 결합을 사용하는 것과 비슷하지만 훨씬 더 멋지게 보입니다.

절을 통해 선택하지 않은 열을 그룹별로 사용하는 것은 비표준입니다. MySQL은 일반적으로 찾은 첫 번째 행의 값을 반환하고 나머지를 버립니다. 조항의 모든 주문은 폐기 된 열 값이 아니라 반환 된 열 값에만 적용됩니다.

중요한 업데이트실제로 작동하지 않는 비기 열을 선택하지만 의존해서는 안됩니다. 당 MySQL 문서 "이것은 주로 그룹별로 명명되지 않은 각각의 비 집합 열의 모든 값이 각 그룹에 대해 동일 할 때 유용합니다. 서버는 다음과 같습니다. 모든 값을 선택할 수 있습니다 각 그룹에서 동일하지 않으면 선택한 값은 불확실합니다.."

5.6.21 기준으로 정렬을 통해 주문을 되돌리는 임시 테이블에서 그룹에 문제가 있음을 알았습니다.

현재 5.7.5 Only_full_group_by는 기본적으로 활성화되어 있습니다. 즉, 비 응집 열을 사용하는 것은 불가능합니다.

보다http://www.cafewebmaster.com/mysql-order-sort-group https://dev.mysql.com/doc/refman/5.6/en/group-by-h-henling.html https://dev.mysql.com/doc/refman/55.7/en/group-by-hinling.html

다른 팁

다음은 다음과 같습니다.

SELECT cur.textID, cur.fromEmail, cur.subject, 
     cur.timestamp, cur.read
FROM incomingEmails cur
LEFT JOIN incomingEmails next
    on cur.fromEmail = next.fromEmail
    and cur.timestamp < next.timestamp
WHERE next.timestamp is null
and cur.toUserID = '$userID' 
ORDER BY LOWER(cur.fromEmail)

기본적으로, 당신은 나중에 행을 검색하면서 테이블 자체에 가입합니다. Where 조항에서 나중에 행이있을 수 없다고 말합니다. 이것은 당신에게 최신 행만 제공합니다.

동일한 타임 스탬프가있는 여러 이메일이있을 수 있다면이 쿼리는 정제해야합니다. 이메일 테이블에 증분 ID 열이있는 경우 다음과 같은 조인을 변경하십시오.

LEFT JOIN incomingEmails next
    on cur.fromEmail = next.fromEmail
    and cur.id < next.id

다음과 같이 그룹으로 쿼리를 감싸서 주문 후 그룹을 수행하십시오.

SELECT t.* FROM (SELECT * FROM table ORDER BY time DESC) t GROUP BY t.from

이미 답장에 지적한 바와 같이, 현재 답변은 잘못된 것입니다.

MySQL 5.6 또는 MySQL 5.7을 사용하는 경우 ONLY_FULL_GROUP_BY, 올바른 (결정 론적) 쿼리는 다음과 같습니다.

SELECT incomingEmails.*
  FROM (
    SELECT fromEmail, MAX(timestamp) `timestamp`
    FROM incomingEmails
    GROUP BY fromEmail
  ) filtered_incomingEmails
  JOIN incomingEmails USING (fromEmail, timestamp)
GROUP BY fromEmail, timestamp

쿼리가 효율적으로 실행 되려면 적절한 인덱싱이 필요합니다.

단순화 목적으로, 나는 그것을 제거했다 LOWER(), 대부분의 경우 사용되지 않습니다.

SQL 표준에 따르면 선택 목록에서 비 응집 열을 사용할 수 없습니다. MySQL은 이러한 사용법 (uless only_full_group_by 모드 사용)을 허용하지만 결과는 예측할 수 없습니다.

only_full_group_by

먼저 메일에서 Min (읽기)을 선택한 다음 Sec

하위 쿼리 접근 방식이 내가 어떤 색인을 입히든 상관없이, 최대 절전 모드를 통해 외부 자체 가입을 얻을 수 없었기 때문에 보여주는 것보다 더 복잡한 쿼리에 대한이 두 가지 접근법에 어려움을 겪었습니다.

이 작업을 수행하는 가장 좋은 (가장 쉬운) 방법은 필요한 필드의 연결을 포함하도록 구성된 것으로 그룹화 한 다음 선택 조항에서 표현식을 사용하여 꺼내는 것입니다. max ()를 수행 해야하는 경우 max () 이상하려는 필드가 항상 연결된 엔티티의 가장 중요한 끝에 있는지 확인하십시오.

이를 이해하는 열쇠는 쿼리가 이러한 다른 필드가 Max ()를 만족시키는 엔티티에 대해 변하지 않는 경우에만 이해 될 수 있다는 것입니다. 이 링크의 바닥 에서이 작업을 수행하는 방법을 설명합니다. http://dev.mysql.com/doc/refman/en/group-by-hidden-columns.html

AM 삽입/업데이트 이벤트 (예 : 트리거와 같은)를 얻을 수 있다면 필드의 연결을 사전 압축 할 수 있다면 색인을 인덱싱 할 수 있으며 쿼리는 그룹이 실제로 최대를 원했던 필드를 넘어서는 것처럼 빠르게됩니다 ( ). 최대 여러 필드를 얻는 데 사용할 수도 있습니다. 나는 그것을 사용하여 중첩 된 세트로 표현 된 다차원 트리에 대한 쿼리를 수행합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top