MySQL: N개의 행을 선택하지만 하나의 열에 고유한 값만 있음
주어진 데이터 집합:
ID Name City Birthyear
1 Egon Spengler New York 1957
2 Mac Taylor New York 1955
3 Sarah Connor Los Angeles 1959
4 Jean-Luc Picard La Barre 2305
5 Ellen Ripley Nostromo 2092
6 James T. Kirk Riverside 2233
7 Henry Jones Chicago 1899
가장 나이가 많은 3명을 찾아야 하는데, 도시마다 한 명씩밖에 없습니다.
만약 세 명의 가장 나이가 많다면, 그건...
- 헨리 존스 / 시카고
- 맥 테일러 / 뉴욕
- 에곤 스팽글러 / 뉴욕
그러나 에곤 스팽글러와 맥 테일러는 모두 뉴욕에 있기 때문에 에곤 스팽글러는 하차하고 다음 사람(사라 코너 / 로스앤젤레스)이 대신 들어올 것입니다.
우아한 해결책이 있습니까?
업데이트:
현재 PConroy의 변형은 가장 빠르고 최상의 솔루션입니다.
SELECT P.*, COUNT(*) AS ct
FROM people P
JOIN (SELECT MIN(Birthyear) AS Birthyear
FROM people
GROUP by City) P2 ON P2.Birthyear = P.Birthyear
GROUP BY P.City
ORDER BY P.Birthyear ASC
LIMIT 10;
그의 "IN"에 대한 원래 쿼리는 큰 데이터 세트에서 매우 느리지만(5분 후 중단됨) 서브 쿼리를 JOIN으로 이동하면 훨씬 속도가 빨라집니다.테스트 환경에서 약 1백만 행을 수행하는 데 약 0.15초가 걸렸습니다.저는 "도시, 출생연도"에 대한 지수와 "생일연도"에 대한 지수를 가지고 있습니다.
참고: 이 내용은 다음과 관련이 있습니다.
가장 우아한 솔루션은 아닐 것입니다. 그리고 성능은IN
더 큰 테이블에서 고통 받을 수 있습니다.
중첩 쿼리는 최소값을 가져옵니다.Birthyear
도시별로이것을 가지고 있는 유일한 기록.Birthyear
외부 쿼리에서 일치합니다.연령별 주문 후 결과를 3개로 제한하면 도시 최고령자 3명을 얻게 됩니다(에곤 스팽글러 하차..).
SELECT Name, City, Birthyear, COUNT(*) AS ct
FROM table
WHERE Birthyear IN (SELECT MIN(Birthyear)
FROM table
GROUP by City)
GROUP BY City
ORDER BY Birthyear DESC LIMIT 3;
+-----------------+-------------+------+----+
| name | city | year | ct |
+-----------------+-------------+------+----+
| Henry Jones | Chicago | 1899 | 1 |
| Mac Taylor | New York | 1955 | 1 |
| Sarah Connor | Los Angeles | 1959 | 1 |
+-----------------+-------------+------+----+
편집 - 추가됨GROUP BY City
외견상, 같은 출생연도를 가진 사람들은 여러 값을 반환할 것입니다.외부 쿼리에서 그룹화하면 도시당 하나의 결과만 반환됩니다. 두 명 이상의 사용자가 최소값을 가질 경우Birthyear
.그ct
칼럼은 그것과 함께 도시에 한 명 이상의 사람이 존재하는지를 보여줄 것입니다.Birthyear
이것은 아마도 가장 우아하고 빠른 해결책은 아니지만 효과가 있을 것입니다.실제 데이터베이스 전문가의 솔루션을 볼 수 있을지 기대됩니다.
select p.* from people p,
(select city, max(age) as mage from people group by city) t
where p.city = t.city and p.age = t.mage
order by p.age desc
그런 거?
SELECT
Id, Name, City, Birthyear
FROM
TheTable
WHERE
Id IN (SELECT TOP 1 Id FROM TheTable i WHERE i.City = TheTable.City ORDER BY Birthyear)
예쁘지는 않지만 동일한 도브를 가진 여러 사람들과도 함께 작업해야 합니다.
테스트 데이터:
select id, name, city, dob
into people
from
(select 1 id,'Egon Spengler' name, 'New York' city , 1957 dob
union all select 2, 'Mac Taylor','New York', 1955
union all select 3, 'Sarah Connor','Los Angeles', 1959
union all select 4, 'Jean-Luc Picard','La Barre', 2305
union all select 5, 'Ellen Ripley','Nostromo', 2092
union all select 6, 'James T. Kirk','Riverside', 2233
union all select 7, 'Henry Jones','Chicago', 1899
union all select 8, 'Blah','New York', 1955) a
쿼리:
select
*
from
people p
left join people p1
ON
p.city = p1.city
and (p.dob > p1.dob and p.id <> p1.id)
or (p.dob = p1.dob and p.id > p1.id)
where
p1.id is null
order by
p.dob
@블람
UPDATED가 ON 대신 USING을 사용하는 것이 좋다는 것을 발견했습니다. 결과적으로 중복된 열을 제거할 것입니다.
SELECT P.*, COUNT(*) AS ct
FROM people P
JOIN (SELECT City, MIN(Birthyear) AS Birthyear
FROM people
GROUP by City) P2 USING(Birthyear, City)
GROUP BY P.City
ORDER BY P.Birthyear ASC
LIMIT 10;
원본 게시물
안녕하세요, 업데이트된 쿼리를 사용하려고 했지만 가입 조건을 추가할 때까지 잘못된 결과를 얻고 있었습니다(또한 가입 선택에 추가 열).문의 사항을 전달합니다. 저는 이것을 사용하고 있습니다.
SELECT P.*, COUNT(*) AS ct
FROM people P
JOIN (SELECT City, MIN(Birthyear) AS Birthyear
FROM people
GROUP by City) P2 ON P2.Birthyear = P.Birthyear AND P2.City = P.City
GROUP BY P.City
ORDER BY P.Birthyear ASC
LIMIT 10;
이론적으로는 마지막 GROUP BY P가 필요하지 않습니다.시티, 하지만 만일을 대비해서 지금은 그곳에 놔뒀어요.아마 나중에 제거할 겁니다
언급URL : https://stackoverflow.com/questions/190702/mysql-select-n-rows-but-with-only-unique-values-in-one-column
'programing' 카테고리의 다른 글
Clion에서 .h 파일에 대한 함수 헤더를 자동으로 생성하는 방법은? (0) | 2023.10.17 |
---|---|
워드프레스에서 비주얼 작곡가를 위한 맞춤 메타박스 지원을 만드는 방법은? (0) | 2023.10.17 |
Docker CentOS - mariadb(종료 상태 0, 예상됨) (0) | 2023.10.12 |
FormDefault 요소는 XSD에서 무엇을 합니까? (0) | 2023.10.12 |
삽입 전 MariaDB 트리거가 작동하지 않습니다. (0) | 2023.10.12 |