মাইএসকিউএলে র‌্যাঙ্ক ফাংশন


155

আমার গ্রাহকদের র‌্যাঙ্ক বের করা দরকার। এখানে আমি আমার প্রয়োজনীয়তার জন্য সংশ্লিষ্ট এএনএসআই স্ট্যান্ডার্ড এসকিউএল কোয়েরি যুক্ত করছি। এটিকে MySQL এ রূপান্তর করতে দয়া করে আমাকে সহায়তা করুন help

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

মাইএসকিউএলে র‌্যাঙ্ক খুঁজে পাওয়ার জন্য কোনও ফাংশন আছে কি?

উত্তর:


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
তিনি যদিও বিভাজনের জন্য জিজ্ঞাসা করেননি? পার্টিশন সম্পর্কে আমার বোঝাপড়াটি হ'ল ফলাফলের সেটটিতে পুরুষ ও মহিলা পৃথক পৃথক র‌্যাঙ্কিং থাকবে।
জেসি illিলন

2
: @Jesse: যদি যে ক্ষেত্রে, আমি সম্প্রতি একটি অনুরূপ প্রশ্নের উত্তর stackoverflow.com/questions/3162389/multiple-ranks-in-one-table
ড্যানিয়েল Vassallo

6
যদি আমি অ্যান এবং বব দুজনকে 4 হিসাবে র‌্যাঙ্ক দিতে চাই তবে কী হবে?
ফাহিম পার্কার

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ডাটাটাইপ রূপান্তর এবং সংক্ষিপ্ত circuiting বিষয় হ্যান্ডেল যোগ করা হয়।

পিএস: টাইয়ের জন্য যাচাই করা সমস্ত শর্ত সরিয়ে এটি সহজেই পার্টিশনের মাধ্যমে সারিতে সংখ্যায় রূপান্তর করা যায়।

| 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    |

ডিবোতে ডিবো <> ফ্রিডল


2
এই সমাধান বা মুকেশের সমাধানটি সঠিক সমাধান হওয়া উচিত। যদিও টেকনিক্যালি আমি আপনাদের উভয়ের বিশ্বাস ছেলেরা 'সমাধান একটি প্রতিনিধিত্ব ঘন র্যাঙ্কিং এবং একটি নিয়মিত ক্রম। পার্থক্যগুলির একটি ভাল ব্যাখ্যা এখানে দেওয়া হয়েছে: sqlservercurry.com/2009/04/…
Modulitos

আপনি কি আমাদেরকে জানাতে পারেন। Php কোডটি ঠিক কীভাবে হওয়া উচিত? আমি অনুসরণ করার চেষ্টা করেছি, কিন্তু উপরের কোডটি কাজ করে না। .Pp ফর্ম্যাট ইনপুট কিভাবে?
স্রষ্টা

এই সমাধান খুব জেনেরিক নয়; যদি rank_column 0. একটি মান আছে এটা কাজ করবে না sqlfiddle.com/#!2/9c5dd/1
মাইক

1
@ মাইকে CAE বিবৃতিতে একটি ELSE বিভাগ যুক্ত করুন:ELSE @rank_count := @rank_count + 1
প্রিন্স ওডাম

1
@ভাষ ORDER BY gender, age DESC?
সালমান এ

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

এটি অবশ্যই একটি দুর্দান্ত উত্তর কারণ আমার একটি পার্টিশন র‌্যাঙ্কিং করা দরকার। ধন্যবাদ জনাব!
কিম স্ট্যাকস

আইএমও এর @ সাম কিডম্যানের উত্তরে সাবলেট হিসাবে একই জটিলতা রয়েছে: ও (এন ^ 2)। তবে মাইএসকিউএলে এটি আরও ভাল করে করা সম্ভব কিনা তা জানেন না।
xmedeko

Onlamp.com/pub/a/mysql/2007/03/29/… একই লাইন বরাবর দুর্দান্ত টিউটোরিয়াল জন্য দেখুন
ফেরিক্স

র‌্যাঙ্ক পেতে স্ব-যোগদান! দারুণ. শেষ অবধি, ভেরিয়েবল ব্যতীত এবং মাইএসকিউএল 8 উইন্ডো ফাংশন ছাড়াই একটি সমাধান । :)
টিমো

24

র‌্যাঙ্ক সহ পার্সেন্টাইল গণনা করার জন্য ড্যানিয়েলের সংস্করণটির একটি টুইট। এছাড়াও একই নম্বরযুক্ত দুটি ব্যক্তি একই পদে পাবে।

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
যদিও এটি পারফরম্যান্সে সত্যই অনুকূল নয়, এটি দুর্দান্ত!
গ্যাসপা79

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
আমি মাইএসকিউএলে নতুন কিন্তু এই সমাধানটি কি ঠিক আছে? মাইএসকিউএল ডক্সে "ব্যবহারকারী ভেরিয়েবলগুলির সাথে জড়িত এক্সপ্রেশনগুলির জন্য মূল্যায়নের ক্রমটি অপরিবর্তিত।" dev.mysql.com/doc/refman/5.7/en/user-variables.html
narduk

13

মাইএসকিউএল 8 দিয়ে শুরু করে, আপনি অবশেষে মাইএসকিউএলে উইন্ডো ফাংশনগুলিও ব্যবহার করতে পারেন: https://dev.mysql.com/doc/refman/8.0/en/window-function.html

আপনার প্রশ্নটি ঠিক একইভাবে লেখা যেতে পারে:

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

এটি ভুল নয় ঠিক এসকিউএল এর পুরানো সংস্করণগুলির সাথে কাজ করে না। প্লাস এটি ছিল একধরনের অনুলিপি এবং তার প্রশ্নের অতীত তাই এটি উত্তরটি ফিট করে বলে মনে হয় না।
newdark-it

4
@ ব্র্যান্ড-এটি মাইএসকিউএল ৮+ এর মধ্যে তাদের জন্য, এই উত্তরটি গুরুত্বপূর্ণ কারণ এটি আমাদের জানতে দেয় যে র্যাঙ্ক এখন উপলব্ধ। আমি যদি এ পর্যন্ত স্ক্রোল না করে থাকি তবে আমি ধরে নেব যে পূর্ববর্তী উত্তরগুলির একমাত্র সমাধান ছিল।
স্টিভ স্মিথ

1
@ স্টিভস্মিথ ভাল পয়েন্ট এমওয়াইএসকিউএল এর নতুন সংস্করণ ব্যবহার করে তাদের জন্য এই উত্তরটি পেয়ে ভাল লাগল।
newdark-it

হ্যাঁ, আমি ব্যবহারকারী ভেরিয়েবল এবং লজিক ব্লক সহ প্রচুর জবাব দিয়ে নিরুৎসাহিত হয়েছি। মাইএসকিউএল এর একটি নতুন সংস্করণ এটি RANK () ফাংশন দিয়ে পার্টিশনগুলির মাধ্যমে একটি অন্তর্নির্মিত অন্তর্নির্মিত প্রস্তাব দেয় যা খুব সহজ করে দেয়।
জেমস বন্ড

5

@ স্যাম, আপনার বক্তব্য ধারণাটিতে দুর্দান্ত তবে আমি মনে করি যে আপনি মাইএসকিউএল ডক্সটি রেফারেন্সযুক্ত পৃষ্ঠায় কী বলছেন - বা আমি ভুল বুঝেছি :-) - এবং আমি কেবল এটি যুক্ত করতে চেয়েছিলাম যাতে কেউ যদি @ এর সাথে অস্বস্তি বোধ করেন তবে ড্যানিয়েলের উত্তর তারা আরও আশ্বস্ত হবে বা কমপক্ষে আরও গভীরতর গভীরভাবে খনন করবে।

আপনি দেখতে পাচ্ছেন যে "@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 ধারাটির , তাই আমি নিশ্চিত যে এটির আগে মূল্যায়ন করার নিশ্চয়তা দেওয়া হয়েছে; মূলত এটিকে দ্বিতীয় করে তোলে, এবং পূর্ববর্তী বিবৃতি দেয়।

আসলে, আপনি একই মাইএসকিউএল ডক্স পৃষ্ঠায় উল্লেখ করেছেন, আপনি মন্তব্যেও একই সমাধান দেখতে পাবেন - এটিই হতে পারে @ ড্যানিয়েল এটি এখান থেকে পেয়েছে; হ্যাঁ, আমি জানি যে এটি মন্তব্যগুলি তবে এটি অফিসিয়াল ডক্স পৃষ্ঠায় মন্তব্য এবং এটি কিছুটা ওজন বহন করে।


এগুলির কোনওটিই ডকুমেন্টেশন দ্বারা ন্যায়সঙ্গত নয়। এটা ঠিক (अस्पष्ट) জল্পনা। সমস্ত উত্তর যেমন একই ব্যবহার করে এবং একই পরিবর্তনশীল লিখতে থাকে, যা ম্যানুয়ালটিতে স্পষ্টভাবে সংজ্ঞায়িত করা হয় না, যদিও ম্যানুয়ালটিতে আপনার প্রত্যাশা মতো কিছু কাজ করা যেতে পারে যা আপনাকে প্রত্যাশা করে বা কী ব্যবহার করে তা বলে না অ-গ্যারান্টিযুক্ত আচরণের বর্ণনা। PS হিসাবে 8.0 হিসাবে SET এর বাইরে ভেরিয়েবল অ্যাসাইনমেন্টটি হ্রাস করা হয়।
ফিলিপ্সি

4

প্রদত্ত মানের র‌্যাঙ্ক নির্ধারণের জন্য সবচেয়ে সোজা ফরোয়ার্ড সমাধান হ'ল এর আগে মানগুলির সংখ্যা গণনা করা। ধরুন আমাদের নিম্নলিখিত মান রয়েছে:

10 20 30 30 30 40
  • সমস্ত 30মান তৃতীয় হিসাবে বিবেচনা করা হয়
  • সমস্ত 40মান ষষ্ঠ (র‌্যাঙ্ক) বা চতুর্থ (ঘন পদ) বিবেচিত হয়

এখন মূল প্রশ্নে ফিরে আসুন। এখানে কিছু নমুনা তথ্য যা ওপিতে বর্ণিত হিসাবে সাজানো হয়েছে (প্রত্যাশিত র‌্যাঙ্কগুলি ডানদিকে যুক্ত করা হবে):

+------+-----------+------+--------+    +------+------------+
| 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)

এই র‌্যাঙ্কিংটি ওরাকল র‌্যাঙ্ক ফাংশনের সাথে মিলে যায় (যেখানে আপনার যদি একই বয়সের লোক থাকে তবে তারা একই পদমর্যাদা পান, এবং তারপরে র‌্যাঙ্কিং অবিচ্ছিন্ন হয়)।

উপরোক্ত সমাধানগুলির মধ্যে একটি সাব-কোয়েরিতে ব্যবহার করা এবং এক ব্যক্তির স্থান নির্ধারণের জন্য এটি থেকে নির্বাচন করা কিছুটা দ্রুত।

এটি প্রত্যেককে র‌্যাঙ্ক করতে ব্যবহার করা যেতে পারে তবে উপরের সমাধানগুলির চেয়ে ধীর।

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

সারণীর সারিগুলির সংখ্যা বাড়লে এটি উপরের সমাধানগুলির তুলনায় অনেক ধীর হয়ে যেতে পারে Person। এটি ও (এন ^ 2) বনাম ও (এন) ধীর।
xmedeko

2

ড্যানিয়েল এবং সালমানের উত্তরগুলির সংমিশ্রণে ইরানডাকের উত্তরটিতে " তবে " এড়াতে , কেউ নীচের "পার্টিশন ওয়ার্কআরউন্ডস" ব্যবহার করতে পারেন

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ফলাফলের মতো একটি ডেটা স্ট্রাকচারকে নিয়ে যাবে । উদাহরণ হিসাবে, নীচে দেখুন। বিশেষত, এই পদ্ধতিটি ব্যবহার করে পার্টিশনসিয়েন্সটি প্রতিটি নতুন পার্টিশনরেঙ্কের জন্য সর্বদা 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.