itsource

그룹의 SQL 선택 멤버

mycopycode 2023. 10. 29. 19:41
반응형

그룹의 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

반응형