문제

이 데이터 세트가 주어지면 :

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 명을 찾아야하지만 모든 도시 중 하나만 찾아야합니다.

그것이 세 명의 가장 오래된 것이라면 ...

  • 헨리 존스 / 시카고
  • 맥 테일러 / 뉴욕
  • Egon Spengler / New York

그러나 Egon Spengler와 Mac Taylor는 뉴욕에 위치하고 있기 때문에 Egon Spengler는 탈락했고 다음 사람 (Sarah Connor / Los Angeles)이 대신 들어올 것입니다.

우아한 솔루션이 있습니까?

업데이트:

현재 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 분 후에 중단)로 인해 매우 느리지 만 하위 쿼리를 조인으로 옮기면 속도가 빨라집니다. 약 0.15 초가 걸렸습니다. 내 테스트 환경에서 1 개의 mio 행. 나는 "City, Birthyear"에 대한 색인이 있고 두 번째는 "Birthyear"에 있습니다.

참고 : 이것은 ...와 관련이 있습니다.

도움이 되었습니까?

해결책

아마도 가장 우아한 솔루션과 IN 더 큰 테이블에서 어려움을 겪을 수 있습니다.

중첩 쿼리가 최소값을 얻습니다 Birthyear 각 도시에 대해. 이것을 가진 기록 만 Birthyear 외부 쿼리에 일치합니다. 나이에 따라 주문한 다음 3 번의 결과로 제한하면 도시에서 가장 오래된 3 명의 가장 나이가 많은 사람들이됩니다 (Egon Spengler는 탈퇴합니다 ..)

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)

예쁘지는 않지만 동일한 DOB를 가진 여러 사람과도 일해야합니다.

테스트 데이터 :

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

@blam

업데이트되었습니다방금 ON 대신 사용하는 것이 좋습니다. 결과에서 중복 열을 제거합니다.

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;

이론적으로 P.City의 마지막 그룹이 필요하지 않아야하지만, 만일을 대비하여 지금 거기에 남겨 두었습니다. 아마 나중에 제거 할 것입니다.

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