그룹의 SQL 선택 멤버
다음과 같은 사용자 테이블이 있는 경우
class | age
--------------
1 20
3 56
2 11
1 12
2 20
그러면 저는 각 반에서 가장 어린 사용자를 쉽게 구할 수 있습니다.
select class, min(age)
from user
group by class;
마찬가지로 min을 max로 대체하면 가장 오래된 것을 얻을 수 있습니다.그런데 어떻게 하면 각 반에서 10번째로 막내(혹은 맏이)를 받을 수 있을까요?그런데 MySql v.5.0을 사용하고 있습니다.
건배.
SELECT a.class,
(
SELECT b.age
FROM users b
WHERE b.class = a.class
ORDER BY age
LIMIT 1,1
) as age
FROM users a
GROUP BY a.class
각 반에서 두 번째로 어립니다.열 번째 막내를 원하신다면 그렇게 하시지요.LIMIT 9,1
그리고 10대째를 원하신다면, 그렇게 하겠죠.ORDER BY age DESC
.
여기서N
선물들Nth
기록.oldest
SELECT *
FROM users k
WHERE N = (SELECT
COUNT( DISTINCT age)
FROM users u
WHERE k.age >= u.age
AND k.class = u.class
GROUP BY u.class)
그리고 그것은Nth
기록.youngest
SELECT *
FROM users k
WHERE N = (SELECT
COUNT(DISTINCT age)
FROM users u
WHERE k.age <= u.age
AND k.class = u.class
GROUP BY u.class)
유일한 sql 독립적인 방법(하위 쿼리 mysql <5가 없더라도)
select u1.class, u1.age, count(*) from user u1 join user u2
on u1.class = u2.class and u1.age >= u2.age
group by u1.class, u1.age
having count(*) = [number]
클래스당 가장 나이가 많은 [숫자]를 드립니다.
select u1.class, u1.age, count(*) from user u1 join user u2
on u1.class = u2.class and u1.age <= u2.age
group by u1.class, u1.age
having count(*) = [number]
학급당 [수] 가장 어린 학생을 받습니다.
두 사람의 나이가 같을 경우 둘 다 반환되기 때문에 작동하지 않을 수 있습니다.하나만 반환하려면 고유 키가 필요하고 쿼리가 더 복잡합니다.
어떤 대답이라도 테이블과 결합하면 정방형의 법칙을 만들어 낼 수 있습니다.
- a JOIN b ON a.class = b.class AND a.age >= b.age
- on average the >= condition will be true for half the class
- 6 people in a class
->6*6/2 = 18
- 10 people in a class
->10*10/2 = 50
-> very rapid growth
테이블 크기가 커지면 성능이 급격히 저하됩니다.만약 물건을 작게 유지하다가 많이 자라지 않는다면, 문제가 됩니까?거기서 당신 전화가...
다른 방법은 코드를 더 많이 사용하지만, 선형적으로 성장합니다.
- 먼저 모든 레코드를 클래스 앤 에이지 순으로 정렬된 IDENTITY 필드와 함께 새 테이블에 삽입합니다.
- 이제 각 클래스에 대해 MIN(id)을 찾습니다.
- 이제 각 클래스별로 = MIN(id) + 8(9번째 장)의 기록을 헹구세요.
마지막 2단계를 하는 방법은 여러 가지가 있습니다.개인적으로는...
SELECT
[USER_WITH_IDS].id,
[USER_WITH_IDS].class,
[USER_WITH_IDS].age
FROM
[USER_WITH_IDS]
WHERE
[USER_WITH_IDS].id = (
SELECT
MIN([min].ID) + 8
FROM
[USER_WITH_IDS] AS [min]
WHERE
[min].class = [USER_WITH_IDS].class
)
이게 의미하는 건...
- 새 ID를 만드는 데 한 번의 패스
- 각 클래스에 대한 MIN(id)을 얻을 수 있는 패스 1개
필요한 기록을 얻을 수 있는 한 번의 패스
그리고 옵티마이저가 얼마나 우수한지에 따라 인덱스(클래스, id)를 사용하면 마지막 두 패스를 하나의 패스로 결합할 수 있습니다.
테이블이나 학급의 크기가 아무리 커도 2, 3번은 통과합니다.정방형이 아닌 선형...
다른 방법은 SQL 쿼리를 for 루프 내부에 배치하는 것이며, 매번 WHERE ...NOT IN 절로 필터링되는 성장 튜플에 새로운 최소값을 추가하는 것입니다.속도에 대해서는 잘 모르겠지만, 매우 큰 데이터 세트(180,000개 이상의 레코드)에서는 매우 빠르게 작동했습니다.SQL과 Python을 섞어서 죄송합니다. 저는 둘 다 초보입니다.SQL에서 루프를 수행할 수 있는 방법이 있을 것이라는 것은 알고 있지만 잘 모르겠습니다.
idx = tuple()
for i in range(n):
qry = '''SELECT class, min(age)
FROM user
WHERE age NOT IN {}
GROUP BY class'''.format(idx)
cur.execute(qry)
data = cur.fetchall()
d = pd.DataFrame(data)
idx = idx + tuple(d['min(age)'])
SQL Server에서는 다음과 같은 작업이 매우 쉽습니다.
select * from( select *, row_number() over(order by age asc) as eldest from class order by age asc) a where a.eldest = 10
MySQL의 경우 이러한 패턴을 참고해 보십시오. http://www.xaprb.com/blog/2006/12/02/how-to-number-rows-in-mysql/
SELECT
userid,
class,
age,
( SELECT COUNT(1) FROM user
WHERE class = c.class AND age > u.age
) AS oldercount
FROM user AS u
WHERE oldercount = 9
GROUP BY class
아니면
SELECT userid,
class,
age
FROM user AS u
WHERE (SELECT COUNT(1) FROM class WHERE class = c.class AND age > u.age) = 9
GROUP BY class
언급URL : https://stackoverflow.com/questions/463054/sql-select-nth-member-of-group
'itsource' 카테고리의 다른 글
최대 높이 설정을 해제하는 방법은? (0) | 2023.10.29 |
---|---|
HSQL 데이터베이스 사용자에게 권한이 없거나 개체를 찾을 수 없음 오류가 발생했습니다. (0) | 2023.10.29 |
Access-Control-Allow-Origin에서는 오리진 null이 허용되지 않습니다. (0) | 2023.10.29 |
PowerShell로 특정 시간 이상 된 파일인지 확인하려면 어떻게 해야 합니까? (0) | 2023.10.29 |
엑셀 시트가 TFS에서 생성되었다는 것을 잊게 하려면 어떻게 해야 합니까? (0) | 2023.10.24 |