MySQL의 순위 함수


155

고객의 순위를 찾아야합니다. 여기 내 요구 사항에 해당하는 ANSI 표준 SQL 쿼리를 추가하고 있습니다. MySQL로 변환하도록 도와주세요.

SELECT RANK() OVER (PARTITION BY Gender ORDER BY Age) AS [Partition by Gender], 
  FirstName, 
  Age,
  Gender 
FROM Person

MySQL에서 순위를 찾는 기능이 있습니까?

답변:


266

한 가지 옵션은 다음과 같은 순위 변수를 사용하는 것입니다.

SELECT    first_name,
          age,
          gender,
          @curRank := @curRank + 1 AS rank
FROM      person p, (SELECT @curRank := 0) r
ORDER BY  age;

(SELECT @curRank := 0)부분은 별도의 SET명령 없이 변수 초기화를 허용합니다 .

테스트 사례 :

CREATE TABLE person (id int, first_name varchar(20), age int, gender char(1));

INSERT INTO person VALUES (1, 'Bob', 25, 'M');
INSERT INTO person VALUES (2, 'Jane', 20, 'F');
INSERT INTO person VALUES (3, 'Jack', 30, 'M');
INSERT INTO person VALUES (4, 'Bill', 32, 'M');
INSERT INTO person VALUES (5, 'Nick', 22, 'M');
INSERT INTO person VALUES (6, 'Kathy', 18, 'F');
INSERT INTO person VALUES (7, 'Steve', 36, 'M');
INSERT INTO person VALUES (8, 'Anne', 25, 'F');

결과:

+------------+------+--------+------+
| first_name | age  | gender | rank |
+------------+------+--------+------+
| Kathy      |   18 | F      |    1 |
| Jane       |   20 | F      |    2 |
| Nick       |   22 | M      |    3 |
| Bob        |   25 | M      |    4 |
| Anne       |   25 | F      |    5 |
| Jack       |   30 | M      |    6 |
| Bill       |   32 | M      |    7 |
| Steve      |   36 | M      |    8 |
+------------+------+--------+------+
8 rows in set (0.02 sec)

52
악의적 인 인라인 초기화의 경우 +1입니다.
찰스

28
그래도 파티션을 요청하지 않았습니까? 파티션에 대한 나의 이해는 결과 집합이 남성과 여성에 대해 별도의 순위를 가질 것이라는 것입니다.
Jesse Dhillon

2
@Jesse :이 경우에 비슷한 질문에 최근 답변했습니다 : stackoverflow.com/questions/3162389/multiple-ranks-in-one-table
Daniel Vassallo

6
Anne과 Bob에게 4 점을 주려면 어떻게해야합니까?
Fahim Parkar

8
이것은 partition by gender분석 함수 의 일부 ( 전체 결과가 아닌 성별 당 순위 값의 "숫자")를 놓치므로 질문의 예를 구현하지 않습니다.
a_horse_with_no_name

53

다음은 파티션에 밀도가 높은 순위를 행에 할당하는 일반적인 솔루션입니다. 사용자 변수를 사용합니다.

CREATE TABLE person (
    id INT NOT NULL PRIMARY KEY,
    firstname VARCHAR(10),
    gender VARCHAR(1),
    age INT
);

INSERT INTO person (id, firstname, gender, age) VALUES
(1,  'Adams',  'M', 33),
(2,  'Matt',   'M', 31),
(3,  'Grace',  'F', 25),
(4,  'Harry',  'M', 20),
(5,  'Scott',  'M', 30),
(6,  'Sarah',  'F', 30),
(7,  'Tony',   'M', 30),
(8,  'Lucy',   'F', 27),
(9,  'Zoe',    'F', 30),
(10, 'Megan',  'F', 26),
(11, 'Emily',  'F', 20),
(12, 'Peter',  'M', 20),
(13, 'John',   'M', 21),
(14, 'Kate',   'F', 35),
(15, 'James',  'M', 32),
(16, 'Cole',   'M', 25),
(17, 'Dennis', 'M', 27),
(18, 'Smith',  'M', 35),
(19, 'Zack',   'M', 35),
(20, 'Jill',   'F', 25);

SELECT person.*, @rank := CASE
    WHEN @partval = gender AND @rankval = age THEN @rank
    WHEN @partval = gender AND (@rankval := age) IS NOT NULL THEN @rank + 1
    WHEN (@partval := gender) IS NOT NULL AND (@rankval := age) IS NOT NULL THEN 1
END AS rnk
FROM person, (SELECT @rank := NULL, @partval := NULL, @rankval := NULL) AS x
ORDER BY gender, age;

변수 할당은 CASE표현식 안에 배치됩니다 . 이것은 이론적으로 평가 문제를 처리합니다. 은 IS NOT NULL데이터 형식 변환 및 단락 문제를 처리하기 위해 추가됩니다.

추신 : 동점을 확인하는 모든 조건을 제거하여 파티션을 통해 행 번호로 쉽게 변환 할 수 있습니다.

| id | firstname | gender | age | rank |
|----|-----------|--------|-----|------|
| 11 | Emily     | F      | 20  | 1    |
| 20 | Jill      | F      | 25  | 2    |
| 3  | Grace     | F      | 25  | 2    |
| 10 | Megan     | F      | 26  | 3    |
| 8  | Lucy      | F      | 27  | 4    |
| 6  | Sarah     | F      | 30  | 5    |
| 9  | Zoe       | F      | 30  | 5    |
| 14 | Kate      | F      | 35  | 6    |
| 4  | Harry     | M      | 20  | 1    |
| 12 | Peter     | M      | 20  | 1    |
| 13 | John      | M      | 21  | 2    |
| 16 | Cole      | M      | 25  | 3    |
| 17 | Dennis    | M      | 27  | 4    |
| 7  | Tony      | M      | 30  | 5    |
| 5  | Scott     | M      | 30  | 5    |
| 2  | Matt      | M      | 31  | 6    |
| 15 | James     | M      | 32  | 7    |
| 1  | Adams     | M      | 33  | 8    |
| 18 | Smith     | M      | 35  | 9    |
| 19 | Zack      | M      | 35  | 9    |

db <> 바이올린 데모


2
이 솔루션 또는 Mukesh의 솔루션이 올바른 솔루션이어야합니다. 기술적으로 나는 두 사람의 솔루션이 모두 일정한 순위가 아니라 밀도높은 순위 라고 생각합니다 . 다음은 차이의 좋은 설명은 다음과 같습니다 sqlservercurry.com/2009/04/... .
modulitos 2016 년

.php 코드가 정확히 어떻게되는지 알려주십시오. 따라하려고했지만 위의 코드가 작동하지 않습니다. .php 형식으로 입력하는 방법?
창조자

이 솔루션은 그리 일반적이지 않습니다. rank_column의 값이 0 이면
mike

1
@mike CASE 명세서에 ELSE 섹션 추가 :ELSE @rank_count := @rank_count + 1
Prince

1
@abhash ORDER BY gender, age DESC?
Salman A

52

가장 많이 답한 답변은 순위가 매겨 지지만 분할되지는 않지만 자체 결합을 수행하여 모든 것을 분할 할 수도 있습니다.

SELECT    a.first_name,
      a.age,
      a.gender,
        count(b.age)+1 as rank
FROM  person a left join person b on a.age>b.age and a.gender=b.gender 
group by  a.first_name,
      a.age,
      a.gender

사용 사례

CREATE TABLE person (id int, first_name varchar(20), age int, gender char(1));

INSERT INTO person VALUES (1, 'Bob', 25, 'M');
INSERT INTO person VALUES (2, 'Jane', 20, 'F');
INSERT INTO person VALUES (3, 'Jack', 30, 'M');
INSERT INTO person VALUES (4, 'Bill', 32, 'M');
INSERT INTO person VALUES (5, 'Nick', 22, 'M');
INSERT INTO person VALUES (6, 'Kathy', 18, 'F');
INSERT INTO person VALUES (7, 'Steve', 36, 'M');
INSERT INTO person VALUES (8, 'Anne', 25, 'F');

답변 :

Bill    32  M   4
Bob     25  M   2
Jack    30  M   3
Nick    22  M   1
Steve   36  M   5
Anne    25  F   3
Jane    20  F   2
Kathy   18  F   1

파티션 순위를 지정해야하기 때문에 이것은 훌륭한 답변입니다. 감사합니다!
Kim 님이

IMO는 @Sam Kidman 's answer : O (n ^ 2)의 subselect와 동일한 복잡성을가집니다. 그러나 dunno는 MySQL에서 더 잘 할 수 있는지 알고 있습니다.
xmedeko

같은 줄을 따라 훌륭한 튜토리얼을 보려면 onlamp.com/pub/a/mysql/2007/03/29/… 를 확인하십시오
ferics2

순위에 오르기 위해 스스로 참여하십시오! 훌륭합니다. 마지막으로 변수없고 MySQL 8 윈도우 기능이없는 솔루션 . :)
Timo

24

순위와 함께 백분위 수를 계산하기위한 Daniel 버전의 조정. 또한 같은 점수를 가진 두 사람은 같은 순위를 갖습니다.

set @totalStudents = 0;
select count(*) into @totalStudents from marksheets;
SELECT id, score, @curRank := IF(@prevVal=score, @curRank, @studentNumber) AS rank, 
@percentile := IF(@prevVal=score, @percentile, (@totalStudents - @studentNumber + 1)/(@totalStudents)*100),
@studentNumber := @studentNumber + 1 as studentNumber, 
@prevVal:=score
FROM marksheets, (
SELECT @curRank :=0, @prevVal:=null, @studentNumber:=1, @percentile:=100
) r
ORDER BY score DESC

샘플 데이터에 대한 쿼리 결과-

+----+-------+------+---------------+---------------+-----------------+
| id | score | rank | percentile    | studentNumber | @prevVal:=score |
+----+-------+------+---------------+---------------+-----------------+
| 10 |    98 |    1 | 100.000000000 |             2 |              98 |
|  5 |    95 |    2 |  90.000000000 |             3 |              95 |
|  6 |    91 |    3 |  80.000000000 |             4 |              91 |
|  2 |    91 |    3 |  80.000000000 |             5 |              91 |
|  8 |    90 |    5 |  60.000000000 |             6 |              90 |
|  1 |    90 |    5 |  60.000000000 |             7 |              90 |
|  9 |    84 |    7 |  40.000000000 |             8 |              84 |
|  3 |    83 |    8 |  30.000000000 |             9 |              83 |
|  4 |    72 |    9 |  20.000000000 |            10 |              72 |
|  7 |    60 |   10 |  10.000000000 |            11 |              60 |
+----+-------+------+---------------+---------------+-----------------+

1
이것이 성능상 실제로 최적은 아니지만 훌륭합니다!
Gaspa79

18

다니엘과 살만의 대답의 조합. 그러나 순위는 관계가있는 연속 시퀀스로 제공되지 않습니다. 대신 다음 순위로 건너 뜁니다. 따라서 최대 값은 항상 행 수에 도달합니다.

    SELECT    first_name,
              age,
              gender,
              IF(age=@_last_age,@curRank:=@curRank,@curRank:=@_sequence) AS rank,
              @_sequence:=@_sequence+1,@_last_age:=age
    FROM      person p, (SELECT @curRank := 1, @_sequence:=1, @_last_age:=0) r
    ORDER BY  age;

스키마 및 테스트 사례 :

CREATE TABLE person (id int, first_name varchar(20), age int, gender char(1));

INSERT INTO person VALUES (1, 'Bob', 25, 'M');
INSERT INTO person VALUES (2, 'Jane', 20, 'F');
INSERT INTO person VALUES (3, 'Jack', 30, 'M');
INSERT INTO person VALUES (4, 'Bill', 32, 'M');
INSERT INTO person VALUES (5, 'Nick', 22, 'M');
INSERT INTO person VALUES (6, 'Kathy', 18, 'F');
INSERT INTO person VALUES (7, 'Steve', 36, 'M');
INSERT INTO person VALUES (8, 'Anne', 25, 'F');
INSERT INTO person VALUES (9, 'Kamal', 25, 'M');
INSERT INTO person VALUES (10, 'Saman', 32, 'M');

산출:

+------------+------+--------+------+--------------------------+-----------------+
| first_name | age  | gender | rank | @_sequence:=@_sequence+1 | @_last_age:=age |
+------------+------+--------+------+--------------------------+-----------------+
| Kathy      |   18 | F      |    1 |                        2 |              18 |
| Jane       |   20 | F      |    2 |                        3 |              20 |
| Nick       |   22 | M      |    3 |                        4 |              22 |
| Kamal      |   25 | M      |    4 |                        5 |              25 |
| Anne       |   25 | F      |    4 |                        6 |              25 |
| Bob        |   25 | M      |    4 |                        7 |              25 |
| Jack       |   30 | M      |    7 |                        8 |              30 |
| Bill       |   32 | M      |    8 |                        9 |              32 |
| Saman      |   32 | M      |    8 |                       10 |              32 |
| Steve      |   36 | M      |   10 |                       11 |              36 |
+------------+------+--------+------+--------------------------+-----------------+

1
나는 MySQL을 처음 사용하지만이 솔루션은 괜찮습니까? MySQL 문서에서 "사용자 변수와 관련된 표현식의 평가 순서는 정의되어 있지 않습니다." dev.mysql.com/doc/refman/5.7/en/user-variables.html
narduk

13

MySQL 8부터는 MySQL에서도 윈도우 기능을 사용할 수 있습니다 : https://dev.mysql.com/doc/refman/8.0/en/window-functions.html

쿼리는 정확히 같은 방식으로 작성 될 수 있습니다.

SELECT RANK() OVER (PARTITION BY Gender ORDER BY Age) AS `Partition by Gender`, 
  FirstName, 
  Age,
  Gender 
FROM Person

이전 버전의 SQL에서는 작동하지 않습니다. 또한 그것은 일종의 복사와 과거의 질문이므로 답변에 맞는 것처럼 느껴지지 않습니다.
newdark-it

4
@ brand-it MySQL 8 이상을 사용하는 사람들에게는 순위가 현재 사용 가능하다는 것을 알려주기 때문에이 답변이 중요합니다. 지금까지 아래로 스크롤하지 않았다면 이전 답변이 유일한 해결책이라고 가정합니다.
Steve Smith

1
@SteveSmith 좋은 점은 최신 버전의 MYSQL을 사용하는 사람들에게이 답변을주는 것이 좋습니다.
newdark-it

그렇습니다. 사용자 변수와 논리 블록에 대한 많은 답변이 권장되지 않습니다. MySQL의 새로운 버전은 파티션별로 내장 된 그룹화를 제공하는 RANK () 함수로 간단하게 할 수 있습니다.
제임스 본드

5

@ Sam, 요점은 개념이 뛰어나지 만 참조 된 페이지에서 MySQL 문서가 말한 것을 잘못 이해했다고 생각합니다. 또는 :-) 오해하고 있습니다. 다니엘의 대답은 그들이 더 안심되거나 적어도 조금 더 깊이 파고들 것입니다.

당신은 볼 "@curRank := @curRank + 1 AS rank"(가) 내부에 SELECT"하나 개의 문장"아니다, 명령문의 그것의 하나 "원자"부분은 안전해야하므로.

참조하는 문서는 명령문의 2 (원자) 부분에서 동일한 사용자 정의 변수가있는 예를 보여줍니다 (예 :) "SELECT @curRank, @curRank := @curRank + 1 AS rank".

하나는 주장 할 수있는 @curRank두 번 다니엘의 대답 @ 사용된다 : (1)이 "@curRank := @curRank + 1 AS rank"(2) "(SELECT @curRank := 0) r"하지만 두 번째 사용량이의 일부이기 때문에 FROM절, 나는 확신이 먼저 계산을 보장 해요; 본질적으로 두 번째이고 앞선 진술입니다.

사실, 당신이 참조한 동일한 MySQL 문서 페이지에서 주석에 동일한 솔루션이 나타납니다. 그래, 나는 그것이 의견이라는 것을 알고 있지만 공식 문서 페이지에 대한 의견이며 그 무게를 가중시킵니다.


이 중 어느 것도 문서에 의해 정당화되지 않습니다. 그것은 단지 (퍼지) 추측입니다. 매뉴얼에는 명시 적으로 정의되지 않은 동일한 변수를 사용하고 쓰는 두 가지 대답이 모두 있지만, 매뉴얼에는 예상 한 내용이나 사용 방법을 말하지 않고 예상대로 작동하는 유용한 텍스트가 많이 있습니다. 보장되지 않은 행동에 대한 설명입니다. PS SET 외부 8.0 변수 할당은 더 이상 사용되지 않습니다.
philipxy

4

주어진 값의 순위를 결정하는 가장 간단한 해결책은 그 전에 값의 수를 세는 것입니다. 다음과 같은 값이 있다고 가정하십시오.

10 20 30 30 30 40
  • 모든 30값은 3 번째 로 간주됩니다
  • 모든 40값은 6 위 (순위) 또는 4 위 (고밀도 순위) 로 간주됩니다

이제 원래 질문으로 돌아갑니다. 다음은 OP에 설명 된대로 정렬 된 일부 샘플 데이터입니다 (예상 순위는 오른쪽에 추가됨).

+------+-----------+------+--------+    +------+------------+
| id   | firstname | age  | gender |    | rank | dense_rank |
+------+-----------+------+--------+    +------+------------+
|   11 | Emily     |   20 | F      |    |    1 |          1 |
|    3 | Grace     |   25 | F      |    |    2 |          2 |
|   20 | Jill      |   25 | F      |    |    2 |          2 |
|   10 | Megan     |   26 | F      |    |    4 |          3 |
|    8 | Lucy      |   27 | F      |    |    5 |          4 |
|    6 | Sarah     |   30 | F      |    |    6 |          5 |
|    9 | Zoe       |   30 | F      |    |    6 |          5 |
|   14 | Kate      |   35 | F      |    |    8 |          6 |
|    4 | Harry     |   20 | M      |    |    1 |          1 |
|   12 | Peter     |   20 | M      |    |    1 |          1 |
|   13 | John      |   21 | M      |    |    3 |          2 |
|   16 | Cole      |   25 | M      |    |    4 |          3 |
|   17 | Dennis    |   27 | M      |    |    5 |          4 |
|    5 | Scott     |   30 | M      |    |    6 |          5 |
|    7 | Tony      |   30 | M      |    |    6 |          5 |
|    2 | Matt      |   31 | M      |    |    8 |          6 |
|   15 | James     |   32 | M      |    |    9 |          7 |
|    1 | Adams     |   33 | M      |    |   10 |          8 |
|   18 | Smith     |   35 | M      |    |   11 |          9 |
|   19 | Zack      |   35 | M      |    |   11 |          9 |
+------+-----------+------+--------+    +------+------------+

계산하기 RANK() OVER (PARTITION BY Gender ORDER BY Age)위해 사라 , 당신은이 쿼리를 사용할 수 있습니다 :

SELECT COUNT(id) + 1 AS rank, COUNT(DISTINCT age) + 1 AS dense_rank
FROM testdata
WHERE gender = (SELECT gender FROM testdata WHERE id = 6)
AND age < (SELECT age FROM testdata WHERE id = 6)

+------+------------+
| rank | dense_rank |
+------+------------+
|    6 |          5 |
+------+------------+

계산하기 RANK() OVER (PARTITION BY Gender ORDER BY Age)위해 모든 행이 쿼리를 사용할 수 있습니다 :

SELECT testdata.id, COUNT(lesser.id) + 1 AS rank, COUNT(DISTINCT lesser.age) + 1 AS dense_rank
FROM testdata
LEFT JOIN testdata AS lesser ON lesser.age < testdata.age AND lesser.gender = testdata.gender
GROUP BY testdata.id

결과는 다음과 같습니다 (결합 된 값이 오른쪽에 추가됨).

+------+------+------------+    +-----------+-----+--------+
| id   | rank | dense_rank |    | firstname | age | gender |
+------+------+------------+    +-----------+-----+--------+
|   11 |    1 |          1 |    | Emily     |  20 | F      |
|    3 |    2 |          2 |    | Grace     |  25 | F      |
|   20 |    2 |          2 |    | Jill      |  25 | F      |
|   10 |    4 |          3 |    | Megan     |  26 | F      |
|    8 |    5 |          4 |    | Lucy      |  27 | F      |
|    6 |    6 |          5 |    | Sarah     |  30 | F      |
|    9 |    6 |          5 |    | Zoe       |  30 | F      |
|   14 |    8 |          6 |    | Kate      |  35 | F      |
|    4 |    1 |          1 |    | Harry     |  20 | M      |
|   12 |    1 |          1 |    | Peter     |  20 | M      |
|   13 |    3 |          2 |    | John      |  21 | M      |
|   16 |    4 |          3 |    | Cole      |  25 | M      |
|   17 |    5 |          4 |    | Dennis    |  27 | M      |
|    5 |    6 |          5 |    | Scott     |  30 | M      |
|    7 |    6 |          5 |    | Tony      |  30 | M      |
|    2 |    8 |          6 |    | Matt      |  31 | M      |
|   15 |    9 |          7 |    | James     |  32 | M      |
|    1 |   10 |          8 |    | Adams     |  33 | M      |
|   18 |   11 |          9 |    | Smith     |  35 | M      |
|   19 |   11 |          9 |    | Zack      |  35 | M      |
+------+------+------------+    +-----------+-----+--------+

3

한 사람 만 순위를 지정하려면 다음을 수행하십시오.

SELECT COUNT(Age) + 1
 FROM PERSON
WHERE(Age < age_to_rank)

이 순위는 oracle RANK 기능에 해당합니다 (동일한 연령대의 사람들이 동일한 순위를 얻은 후 그 이후의 순위는 비 연속적 임).

하위 쿼리에서 위의 솔루션 중 하나를 사용하고 한 사람의 순위를 얻기 위해 선택하는 것보다 약간 빠릅니다.

이것은 모든 사람의 순위를 매기는 데 사용될 수 있지만 위의 솔루션보다 느립니다.

SELECT
  Age AS age_var,
(
  SELECT COUNT(Age) + 1
  FROM Person
  WHERE (Age < age_var)
 ) AS rank
 FROM Person

테이블 의 행 수가 증가 하면 위의 솔루션보다 훨씬 느려질 수 있습니다 Person. 그것의 O (N ^ 2) VS O (N) 느린.
xmedeko

2

Erandac의 답변에서 Daniel과 Salman의 답변을 조합 하여 " 그러나 " 를 피하기 위해 다음 "파티션 해결 방법"중 하나를 사용할 수 있습니다.

SELECT customerID, myDate

  -- partition ranking works only with CTE / from MySQL 8.0 on
  , RANK() OVER (PARTITION BY customerID ORDER BY dateFrom) AS rank, 

  -- Erandac's method in combination of Daniel's and Salman's
  -- count all items in sequence, maximum reaches row count.
  , IF(customerID=@_lastRank, @_curRank:=@_curRank, @_curRank:=@_sequence+1) AS sequenceRank
  , @_sequence:=@_sequence+1 as sequenceOverAll

  -- Dense partition ranking, works also with MySQL 5.7
  -- remember to set offset values in from clause
  , IF(customerID=@_lastRank, @_nxtRank:=@_nxtRank, @_nxtRank:=@_nxtRank+1 ) AS partitionRank
  , IF(customerID=@_lastRank, @_overPart:=@_overPart+1, @_overPart:=1 ) AS partitionSequence

  , @_lastRank:=customerID
FROM myCustomers, 
  (SELECT @_curRank:=0, @_sequence:=0, @_lastRank:=0, @_nxtRank:=0, @_overPart:=0 ) r
ORDER BY customerID, myDate

이 코드 스 니펫의 세 번째 변형에서 파티션 순위는 연속 순위 번호를 반환합니다. 이것은 rank() over partition by결과 와 비슷한 데이터 구조로 이어질 것 입니다. 예를 들어 아래를 참조하십시오. 특히 partitionSequence는 이 방법을 사용하여 새로운 partitionRank마다 항상 1로 시작합니다 .

customerID    myDate   sequenceRank (Erandac)
                          |    sequenceOverAll
                          |     |   partitionRank
                          |     |     | partitionSequence
                          |     |     |    | lastRank
... lines ommitted for clarity
40    09.11.2016 11:19    1     44    1   44    40
40    09.12.2016 12:08    1     45    1   45    40
40    09.12.2016 12:08    1     46    1   46    40
40    09.12.2016 12:11    1     47    1   47    40
40    09.12.2016 12:12    1     48    1   48    40
40    13.10.2017 16:31    1     49    1   49    40
40    15.10.2017 11:00    1     50    1   50    40
76    01.07.2015 00:24    51    51    2    1    76
77    04.08.2014 13:35    52    52    3    1    77
79    15.04.2015 20:25    53    53    4    1    79
79    24.04.2018 11:44    53    54    4    2    79
79    08.10.2018 17:37    53    55    4    3    79
117   09.07.2014 18:21    56    56    5    1   117
119   26.06.2014 13:55    57    57    6    1   119
119   02.03.2015 10:23    57    58    6    2   119
119   12.10.2015 10:16    57    59    6    3   119
119   08.04.2016 09:32    57    60    6    4   119
119   05.10.2016 12:41    57    61    6    5   119
119   05.10.2016 12:42    57    62    6    6   119
...

0
select id,first_name,gender,age,
rank() over(partition by gender order by age) rank_g
from person

CREATE TABLE person (id int, first_name varchar(20), age int, gender char(1));

INSERT INTO person VALUES (1, 'Bob', 25, 'M');
INSERT INTO person VALUES (2, 'Jane', 20, 'F');
INSERT INTO person VALUES (3, 'Jack', 30, 'M');
INSERT INTO person VALUES (4, 'Bill', 32, 'M');
INSERT INTO person VALUES (5, 'Nick', 22, 'M');
INSERT INTO person VALUES (6, 'Kathy', 18, 'F');
INSERT INTO person VALUES (7, 'Steve', 36, 'M');
INSERT INTO person VALUES (8, 'Anne', 25, 'F');
INSERT INTO person VALUES (9,'AKSH',32,'M');
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.