it-source

다중 컬럼 ASC 및 DESC별 MySQL 주문

criticalcode 2023. 10. 18. 22:12
반응형

다중 컬럼 ASC 및 DESC별 MySQL 주문

나는 MYSQL 테이블 2개와 사용자 및 점수를 가지고 있습니다.세부 정보:

  • 사용자 테이블:

enter image description here

  • 점수표:

enter image description here

의도는 포인트 필드 정렬 DESC(하강) 콤바인 avg_time 필드 정렬 ASC(상승)를 가진 사용자 목록 20명을 얻는 것입니다.쿼리를 사용합니다.

SELECT users.username, scores.point, scores.avg_time
FROM scores, users
WHERE scores.user_id = users.id
GROUP BY users.username
ORDER BY scores.point DESC, scores.avg_time
LIMIT 0, 20

결과는 다음과 같습니다.

enter image description here

첫 번째 선이 정확히 점 = 100이고 avg_time = 60이므로 결과가 틀립니다.

제가 원하는 결과는 다음과 같습니다.

username    point    avg_time
demo123      100        60
demo123456   100       100
demo         90        120

여러 가지 질문으로 여러 번 시도했지만 여전히 결과가 틀렸습니다.해결책을 좀 알려주시겠습니까?

네, 고객님께서 원하시는 바를 지금은 이해한다고 생각합니다. 질의 전에 확인하도록 하겠습니다.당신은 각 사용자에 대해 하나의 레코드를 원합니다.각 사용자에 대해 BEST POINTS 점수 기록을 원할 수 있습니다.사용자당 가장 좋은 점수 중 평균 시간이 가장 좋은 것을 원합니다.모든 사용자가 "최상" 값을 갖게 되면 최종 결과를 최상의 점수로 먼저 정렬하기를 원합니다.거의 대회 순위 같아요.

그럼 이제 질문입니다.위 진술이 정확하다면, 1인당 최고의 포인트/평균 시간을 얻고 해당 항목에 "순위"를 부여하는 것부터 시작해야 합니다.이 작업은 MySQL @ 변수를 사용하여 쉽게 수행할 수 있습니다.그러면, 그 기록들을 각자 1등으로만 유지하는 해빙 조항만 넣으시면 됩니다.가장 좋은 점수와 가장 짧은 평균 시간을 기준으로 순서를 적용합니다.

select
      U.UserName,
      PreSortedPerUser.Point,
      PreSortedPerUser.Avg_Time,
      @UserRank := if( @lastUserID = PreSortedPerUser.User_ID, @UserRank +1, 1 ) FinalRank,
      @lastUserID := PreSortedPerUser.User_ID
   from
      ( select
              S.user_id,
              S.point,
              S.avg_time
           from
              Scores S
           order by
              S.user_id,
              S.point DESC,
              S.Avg_Time ) PreSortedPerUser
         JOIN Users U
            on PreSortedPerUser.user_ID = U.ID,
      ( select @lastUserID := 0,
               @UserRank := 0 ) sqlvars 
   having
      FinalRank = 1
   order by
      Point Desc,
      Avg_Time

SQLFiddle에서 처리한 결과

답변을 얻기 위해 필요한 인라인 @변수로 인해 각 행의 끝에는 두 개의 추가 열이 있습니다.이것들은 단지 "왼쪽"일 뿐이며, 여러분이 하려는 어떤 실제 출력 프레젠테이션에서도 무시될 수 있습니다.또는 원하는 몇 개의 열을 얻기 위해 전체를 한 레벨 이상 감쌀 수 있습니다.

select 
      PQ.UserName,
      PQ.Point,
      PQ.Avg_Time
   from
      ( entire query above pasted here ) as PQ

테이블 관계에 대한 이해를 잘못하신 것 같습니다.

사용자 : 점수 = 1 : *

그저.join해결책이 아닙니다.

이것이 당신의 의도입니까?

SELECT users.username, avg(scores.point), avg(scores.avg_time)
FROM scores, users
WHERE scores.user_id = users.id
GROUP BY users.username
ORDER BY avg(scores.point) DESC, avg(scores.avg_time)
LIMIT 0, 20

(이 쿼리는 각 사용자의 평균 포인트와 평균 avg_time을 descpoint별로 가져오기 위해 사용합니다. asc)avg_time

만약 당신이 각 점수 순위를 얻고 싶다면? 사용하세요.left outer join

SELECT users.username, scores.point, scores.avg_time
FROM scores left outer join users on scores.user_id = users.id
ORDER BY scores.point DESC, scores.avg_time
LIMIT 0, 20

@DRAPP는 천재입니다.저는 그가 어떻게 자신의 SQL을 코딩하는지 이해하지 못했기 때문에 제 자신이 이해할 수 있도록 코딩을 시도했습니다.


    SELECT 
      f.username,
      f.point,
      f.avg_time
    FROM
      (
      SELECT
        userscores.username,
        userscores.point,
        userscores.avg_time
      FROM
        (
        SELECT
          users.username,
          scores.point,
          scores.avg_time
        FROM
          scores
        JOIN users
        ON scores.user_id = users.id
        ORDER BY scores.point DESC
        ) userscores
      ORDER BY
        point DESC,
        avg_time
      ) f
    GROUP BY f.username
    ORDER BY point DESC

@variables 사용자 대신 GROUP BY를 사용하여 동일한 결과를 얻을 수 있습니다.

기본 순서에 따라 pk ID ,로 그룹화하므로 결과는
이름 점 점 avg_time
= 4o123 10090 ---> id= 4
= 7o123456 100 100 ---> id= 7
= 1o 90 120 ---> id= 1

언급URL : https://stackoverflow.com/questions/13694907/mysql-order-by-multiple-column-asc-and-desc

반응형