মাইএসকিউএল দিয়ে, আমি কীভাবে একটি টেবিলের রেকর্ড সূচকযুক্ত একটি কলাম তৈরি করতে পারি?


100

আমি কোয়েরি থেকে আসল সারি নম্বর পেতে কোন উপায় আছে?

আমি স্কোর নামে একটি ক্ষেত্র দ্বারা লীগ_গর্ল নামে একটি সারণী অর্ডার করতে সক্ষম হতে চাই; এবং ব্যবহারকারীর নাম এবং সেই ব্যবহারকারীর আসল সারি অবস্থান ফিরিয়ে দিন।

আমি ব্যবহারকারীদের র‌্যাঙ্ক করতে চাই তাই আমি বলতে পারি যে কোনও নির্দিষ্ট ব্যবহারকারী কোথায় আছেন, অর্থাৎ। জো 200 এর মধ্যে 100 অবস্থান, অর্থাৎ

User Score Row
Joe  100    1
Bob  50     2
Bill 10     3

আমি এখানে কয়েকটি সমাধান দেখেছি কিন্তু আমি তাদের বেশিরভাগ ক্ষেত্রেই চেষ্টা করেছি এবং এর মধ্যে কেউই প্রকৃতপক্ষে সারির নম্বরটি দেয় না।

আমি এটি চেষ্টা করেছি:

SELECT position, username, score
FROM (SELECT @row := @row + 1 AS position, username, score 
       FROM league_girl GROUP BY username ORDER BY score DESC) 

হিসাবে প্রাপ্ত

... তবে সারির অবস্থানটি ফিরে আসবে বলে মনে হচ্ছে না।

কোন ধারনা?


একটি দায়ের করা নাম সারি বা আপনি প্রাথমিক কী দ্বারা অর্ডার করতে চান?
সরফরাজ

এসকিউএল-এ সারি সংখ্যাগুলি সত্যই গুরুত্বপূর্ণ নয়। আপনার যা করা উচিত তা হ'ল আপনার টেবিলে একটি স্বয়ংক্রিয় বর্ধিত প্রাথমিক কী যুক্ত করা।
simendsjo

9
প্রাথমিক কীটি কোনও সারি শনাক্তকারীকে কখনই পাওয়া উচিত না কারণ তারা আসল সারি অবস্থানের জন্য নির্ভরযোগ্য নয়।
দ্যবাউন্ডার

3
এছাড়াও, যেহেতু সারি সংখ্যাটি স্কোরের একটি ফাংশন হবে যা আমি ধরে নিলাম এটি কোনও স্থির মান নয়, এটি একটি স্বয়ংক্রিয় বর্ধিত মান (প্রাথমিক কী বা না) তৈরি করে উদ্দেশ্যযুক্ত ফলাফল দেয় না।
kasperjj

আপনি কোনও কাস্টম ফাংশনের জন্য কুৎসিত সংরক্ষণ করতে চাইতে পারেন, ডাটামেকসেসেন্স.com
mysql-

উত্তর:


174

আপনি নিম্নলিখিত চেষ্টা করতে পারেন:

SELECT  l.position, 
        l.username, 
        l.score,
        @curRow := @curRow + 1 AS row_number
FROM    league_girl l
JOIN    (SELECT @curRow := 0) r;

JOIN (SELECT @curRow := 0)অংশ আলাদা প্রয়োজন ছাড়া পরিবর্তনশীল আরম্ভের পারবেন SETকমান্ড।

পরীক্ষা ক্ষেত্রে:

CREATE TABLE league_girl (position int, username varchar(10), score int);
INSERT INTO league_girl VALUES (1, 'a', 10);
INSERT INTO league_girl VALUES (2, 'b', 25);
INSERT INTO league_girl VALUES (3, 'c', 75);
INSERT INTO league_girl VALUES (4, 'd', 25);
INSERT INTO league_girl VALUES (5, 'e', 55);
INSERT INTO league_girl VALUES (6, 'f', 80);
INSERT INTO league_girl VALUES (7, 'g', 15);

পরীক্ষার প্রশ্ন:

SELECT  l.position, 
        l.username, 
        l.score,
        @curRow := @curRow + 1 AS row_number
FROM    league_girl l
JOIN    (SELECT @curRow := 0) r
WHERE   l.score > 50;

ফলাফল:

+----------+----------+-------+------------+
| position | username | score | row_number |
+----------+----------+-------+------------+
|        3 | c        |    75 |          1 |
|        5 | e        |    55 |          2 |
|        6 | f        |    80 |          3 |
+----------+----------+-------+------------+
3 rows in set (0.00 sec)

19
আপনি এই মত কমা দিয়ে বিবৃতিটি @curRowপ্রতিস্থাপন করে আরম্ভ করতে পারেন JOIN:FROM league_girl l, (SELECT @curRow := 0) r
মাইক

2
@ মাইক: সত্য। এবং এটি সম্ভবত আরও সুন্দর। এই টিপ ভাগ করে নেওয়ার জন্য ধন্যবাদ।
ড্যানিয়েল ভ্যাসাল্লো

2
@ এসএমএইএনজিআই মাইএসকিউএল প্রয়োজন প্রতিটি "উত্সযুক্ত টেবিল" একটি নাম দেওয়া উচিত। আমি এটিকে "আর" কল করার সিদ্ধান্ত নিয়েছি :) ... এটির ক্ষেত্রে এর উদ্দেশ্য খুব কম, তবে আপনি সাধারনত এটি উত্সযুক্ত টেবিলের বৈশিষ্ট্যগুলিকে উল্লেখ করতে ব্যবহার করতে চাইবেন, যেন এটি একটি বাস্তব টেবিল।
ড্যানিয়েল ভ্যাসালো

20
লোকেদের সচেতন হওয়া উচিত যে কোনও ক্রম সংঘটিত হওয়ার আগে এই সারির নম্বরটি গণনা করা হচ্ছে , যাতে ক্রমটি ক্রমের ক্রম পরিবর্তন করে তবে সংখ্যাগুলি ঝাঁপিয়ে উঠতে পারে।
...

7
এই সারির নম্বরটি গণনার পরেও কি উপায় আছে ORDER BY?
পিয়েরে লেস্পিনে


7

এখানে আমি ব্যবহৃত টেমপ্লেটের কাঠামোটি আসবে:

  select
          /*this is a row number counter*/
          ( select @rownum := @rownum + 1 from ( select @rownum := 0 ) d2 ) 
          as rownumber,
          d3.*
  from 
  ( select d1.* from table_name d1 ) d3

এবং এখানে আমার কাজের কোড:

select     
           ( select @rownum := @rownum + 1 from ( select @rownum := 0 ) d2 ) 
           as rownumber,
           d3.*
from
(   select     year( d1.date ), month( d1.date ), count( d1.id )
    from       maindatabase d1
    where      ( ( d1.date >= '2013-01-01' ) and ( d1.date <= '2014-12-31' ) )
    group by   YEAR( d1.date ), MONTH( d1.date ) ) d3

নিখুঁত, মোহন এবং টেমপ্লেটের মতো কাজগুলিকে প্যারামিটার হিসাবে সাবকোয়ারির সাথে পুনরায় ব্যবহার করা যেতে পারে ..
জাভায়েল

আপনার বেস ক্যোয়ারী GROUP BY
Dave R

4

আপনি ব্যবহার করতে পারেন

SELECT @curRow := ifnull(@curRow,0) + 1 Row, ...

কাউন্টার ভেরিয়েবল আরম্ভ করার জন্য।


3
@curRowআপনি বর্তমান সেশনে এই ক্যোয়ারীটি শেষ বার চালানোর সময় থেকে এখনও একটি মান থাকতে পারে।
বিল কারভিন

সত্য, তবে কেবল যদি আপনি একই সংযোগের উদাহরণটিতে পুনরায় জিজ্ঞাসা করছেন। সংযোগটি বন্ধ হয়ে গেলে স্থানীয় পরিবর্তনগুলি স্বয়ংক্রিয়ভাবে নিষ্পত্তি হয়।
হৃদয়

হ্যাঁ, আমি যখন "বর্তমান অধিবেশনে" বলেছিলাম তখন এটাই বোঝা গেল।
বিল কারভিন

3

ধরে নিই যে মাইএসকিউএল এটি সমর্থন করে, আপনি এটি একটি স্ট্যান্ডার্ড এসকিউএল উপকোয়ারি দিয়ে সহজেই করতে পারেন:

select 
    (count(*) from league_girl l1 where l2.score > l1.score and l1.id <> l2.id) as position,
    username,
    score
from league_girl l2
order by score;

বৃহত পরিমাণে প্রদর্শিত ফলাফলের জন্য, এটি কিছুটা ধীর হয়ে যাবে এবং পরিবর্তে আপনি স্ব-যোগদানে স্যুইচ করতে চাইবেন।


3

ফিল্ড স্কোর অনুসারে অর্ডার দেওয়ার পরে যদি আপনি কেবল একটি নির্দিষ্ট ব্যবহারকারীর অবস্থান জানতে চান তবে আপনি কেবল আপনার টেবিল থেকে সমস্ত সারিটি নির্বাচন করতে পারেন যেখানে ফিল্ড স্কোর বর্তমান ব্যবহারকারীর স্কোরের চেয়ে বেশি। এবং এই বর্তমান ব্যবহারকারীর কোন অবস্থান জানতে সারি নম্বরটি +1 ব্যবহার করুন।

ধরে নিচ্ছেন যে আপনার টেবিলটি league_girlএবং আপনার প্রাথমিক ক্ষেত্রটি id, আপনি এটি ব্যবহার করতে পারেন:

SELECT count(id) + 1 as rank from league_girl where score > <your_user_score>

0

আমি আসল উত্তরটি অবিশ্বাস্যভাবে সহায়ক বলে খুঁজে পেয়েছি তবে আমি যে সারিটি সন্নিবেশ করছিলাম তার উপর ভিত্তি করে সারিগুলির একটি নির্দিষ্ট সেটও ধরতে চেয়েছিলাম। এর মতো, আমি পুরো মূল উত্তরটি একটি সাবকোয়রিতে মুড়েছি যাতে আমি সন্নিবেশ করানো সারি নম্বরটি উল্লেখ করতে পারি।

SELECT * FROM 
( 
    SELECT *, @curRow := @curRow + 1 AS "row_number"
    FROM db.tableName, (SELECT @curRow := 0) r
) as temp
WHERE temp.row_number BETWEEN 1 and 10;

সাবকিউরিতে সাবকিউরিটি রাখা খুব দক্ষ নয়, সুতরাং আপনার এসকিউএল সার্ভারটি এই কোয়েরিটি পরিচালনা করে, বা পুরো টেবিলটি আনা এবং অ্যাপ্লিকেশন / ওয়েব সার্ভারকে সারিগুলির সাথে সামঞ্জস্য করার পরে আপনি আরও ভাল ফলাফল পেয়েছেন কিনা তা পরীক্ষা করে দেখার বিষয় হবে it ।

ব্যক্তিগতভাবে আমার এসকিউএল সার্ভার অত্যধিক ব্যস্ত নয়, তাই এটি নেস্টেড সাবকোয়ারিগুলি পরিচালনা করা পছন্দনীয়।


0

আমি জানি ওপি একটি mysqlউত্তর চাইছে তবে আমি যেহেতু অন্যান্য উত্তরগুলি আমার পক্ষে কাজ করে না,

  • তাদের বেশিরভাগের সাথে ব্যর্থ হয় order by
  • অথবা এগুলি কেবল খুব অদক্ষ এবং চর্বিযুক্ত টেবিলের জন্য আপনার ক্যোয়ারীটিকে খুব ধীর করে তোলে

সুতরাং আমার মতো অন্যদের জন্য সময় বাঁচানোর জন্য, ডাটাবেস থেকে তাদের পুনরুদ্ধার করার পরে সারিটি সূচক করুন

পিএইচপি মধ্যে উদাহরণ:

$users = UserRepository::loadAllUsersAndSortByScore();

foreach($users as $index=>&$user){
    $user['rank'] = $index+1;
}

পিএইচপি-তে উদাহরণস্বরূপ অফসেট এবং পেজিংয়ের সীমা ব্যবহার করে:

$limit = 20; //page size
$offset = 3; //page number

$users = UserRepository::loadAllUsersAndSortByScore();

foreach($users as $index=>&$user){
    $user['rank'] = $index+1+($limit*($offset-1));
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.