প্রতিটি গ্রুপে শেষ রেকর্ড পুনরুদ্ধার করা হচ্ছে - মাইএসকিউএল


951

messagesনীচে দেখানো আছে এমন একটি টেবিল রয়েছে যাতে ডেটা রয়েছে:

Id   Name   Other_Columns
-------------------------
1    A       A_data_1
2    A       A_data_2
3    A       A_data_3
4    B       B_data_1
5    B       B_data_2
6    C       C_data_1

যদি আমি একটি ক্যোয়ারী চালনা করি তবে আমি select * from messages group by nameফলাফলটি এইভাবে পাব:

1    A       A_data_1
4    B       B_data_1
6    C       C_data_1

কোয়েরিতে নিম্নলিখিত ফলাফলটি ফিরে আসবে?

3    A       A_data_3
5    B       B_data_2
6    C       C_data_1

অর্থাৎ, প্রতিটি গ্রুপের শেষ রেকর্ডটি ফিরিয়ে দেওয়া উচিত।

বর্তমানে, এটি আমি যে ক্যোয়ারীটি ব্যবহার করছি:

SELECT
  *
FROM (SELECT
  *
FROM messages
ORDER BY id DESC) AS x
GROUP BY name

তবে এটি অত্যন্ত অদক্ষ মনে হচ্ছে। একই ফলাফল অর্জনের জন্য অন্য কোনও উপায়?


2
গ্রহণযোগ্য উত্তর দেখার stackoverflow.com/questions/1379565/... আরও কার্যকর সমাধান জন্য
eyaler


7
কেন আপনি কেবল ডিইএসসি যুক্ত করতে পারবেন না, অর্থাত্ ডিইএসসি নামে বার্তা গোষ্ঠী থেকে * নির্বাচন করুন
কিম প্রিন্স


2
@ কিমপ্রিন্স মনে হচ্ছে আপনি যে উত্তরটি প্রস্তাব করছেন তা যেমন প্রত্যাশিত হয় তা করে না! আমি কেবল আপনার পদ্ধতিটি চেষ্টা করেছি এবং এটি প্রতিটি গোষ্ঠীর জন্য প্রথম সারিতে নিয়েছে এবং ডিইএসসি-কে আদেশ দিয়েছে। এটি প্রতিটি গ্রুপের শেষ সারিটি নেয় না
আয়রাত 22'1717

উত্তর:


966

মাইএসকিউএল ৮.০ এখন প্রায় সকল জনপ্রিয় এসকিউএল বাস্তবায়নের মতো উইন্ডোটিং ফাংশন সমর্থন করে। এই স্ট্যান্ডার্ড সিনট্যাক্সের সাহায্যে আমরা প্রতি গ্রুপ-টি-তে সবচেয়ে বড়-এন-লিখতে পারি:

WITH ranked_messages AS (
  SELECT m.*, ROW_NUMBER() OVER (PARTITION BY name ORDER BY id DESC) AS rn
  FROM messages AS m
)
SELECT * FROM ranked_messages WHERE rn = 1;

নীচে আমি 2009 সালে এই প্রশ্নের জন্য লিখেছি মূল উত্তর:


আমি সমাধানটি এইভাবে লিখি:

SELECT m1.*
FROM messages m1 LEFT JOIN messages m2
 ON (m1.name = m2.name AND m1.id < m2.id)
WHERE m2.id IS NULL;

পারফরম্যান্স সম্পর্কে, আপনার ডেটার প্রকৃতির উপর নির্ভর করে একটি সমাধান বা অন্যটি আরও ভাল হতে পারে। সুতরাং আপনার উভয় প্রশ্নের পরীক্ষা করা উচিত এবং আপনার ডাটাবেসের ভিত্তিতে পারফরম্যান্সে আরও ভাল ব্যবহার করা উচিত।

উদাহরণস্বরূপ, আমার কাছে স্ট্যাকওভারফ্লো অগাস্ট ডেটা ডাম্পের একটি অনুলিপি রয়েছে । আমি এটি বেঞ্চমার্কিংয়ের জন্য ব্যবহার করব। Postsসারণীতে 1,114,357 সারি রয়েছে। এটি আমার ম্যাকবুক প্রো 2.40GHz এ মাইএসকিউএল 5.0.75 এ চলছে ।

প্রদত্ত ব্যবহারকারীর আইডি (আমার) জন্য সর্বাধিক সাম্প্রতিক পোস্ট খুঁজতে আমি একটি কোয়েরি লিখব।

প্রথমে সাবকিউরিতে ইরিক দ্বারা দেখানো কৌশলটি ব্যবহার করুন GROUP BY:

SELECT p1.postid
FROM Posts p1
INNER JOIN (SELECT pi.owneruserid, MAX(pi.postid) AS maxpostid
            FROM Posts pi GROUP BY pi.owneruserid) p2
  ON (p1.postid = p2.maxpostid)
WHERE p1.owneruserid = 20860;

1 row in set (1 min 17.89 sec)

এমনকি EXPLAINবিশ্লেষণ 16 সেকেন্ডেরও বেশি সময় নেয়:

+----+-------------+------------+--------+----------------------------+-------------+---------+--------------+---------+-------------+
| id | select_type | table      | type   | possible_keys              | key         | key_len | ref          | rows    | Extra       |
+----+-------------+------------+--------+----------------------------+-------------+---------+--------------+---------+-------------+
|  1 | PRIMARY     | <derived2> | ALL    | NULL                       | NULL        | NULL    | NULL         |   76756 |             | 
|  1 | PRIMARY     | p1         | eq_ref | PRIMARY,PostId,OwnerUserId | PRIMARY     | 8       | p2.maxpostid |       1 | Using where | 
|  2 | DERIVED     | pi         | index  | NULL                       | OwnerUserId | 8       | NULL         | 1151268 | Using index | 
+----+-------------+------------+--------+----------------------------+-------------+---------+--------------+---------+-------------+
3 rows in set (16.09 sec)

Now ব্যবহার করা একই ক্যোয়ারী ফল আমার কৌশল সঙ্গে LEFT JOIN:

SELECT p1.postid
FROM Posts p1 LEFT JOIN posts p2
  ON (p1.owneruserid = p2.owneruserid AND p1.postid < p2.postid)
WHERE p2.postid IS NULL AND p1.owneruserid = 20860;

1 row in set (0.28 sec)

EXPLAINবিশ্লেষণ দেখায় উভয় টেবিল তাদের ইনডেক্স ব্যবহার করতে পারবেন আছেন:

+----+-------------+-------+------+----------------------------+-------------+---------+-------+------+--------------------------------------+
| id | select_type | table | type | possible_keys              | key         | key_len | ref   | rows | Extra                                |
+----+-------------+-------+------+----------------------------+-------------+---------+-------+------+--------------------------------------+
|  1 | SIMPLE      | p1    | ref  | OwnerUserId                | OwnerUserId | 8       | const | 1384 | Using index                          | 
|  1 | SIMPLE      | p2    | ref  | PRIMARY,PostId,OwnerUserId | OwnerUserId | 8       | const | 1384 | Using where; Using index; Not exists | 
+----+-------------+-------+------+----------------------------+-------------+---------+-------+------+--------------------------------------+
2 rows in set (0.00 sec)

আমার Postsটেবিলের জন্য এখানে ডিডিএল রয়েছে:

CREATE TABLE `posts` (
  `PostId` bigint(20) unsigned NOT NULL auto_increment,
  `PostTypeId` bigint(20) unsigned NOT NULL,
  `AcceptedAnswerId` bigint(20) unsigned default NULL,
  `ParentId` bigint(20) unsigned default NULL,
  `CreationDate` datetime NOT NULL,
  `Score` int(11) NOT NULL default '0',
  `ViewCount` int(11) NOT NULL default '0',
  `Body` text NOT NULL,
  `OwnerUserId` bigint(20) unsigned NOT NULL,
  `OwnerDisplayName` varchar(40) default NULL,
  `LastEditorUserId` bigint(20) unsigned default NULL,
  `LastEditDate` datetime default NULL,
  `LastActivityDate` datetime default NULL,
  `Title` varchar(250) NOT NULL default '',
  `Tags` varchar(150) NOT NULL default '',
  `AnswerCount` int(11) NOT NULL default '0',
  `CommentCount` int(11) NOT NULL default '0',
  `FavoriteCount` int(11) NOT NULL default '0',
  `ClosedDate` datetime default NULL,
  PRIMARY KEY  (`PostId`),
  UNIQUE KEY `PostId` (`PostId`),
  KEY `PostTypeId` (`PostTypeId`),
  KEY `AcceptedAnswerId` (`AcceptedAnswerId`),
  KEY `OwnerUserId` (`OwnerUserId`),
  KEY `LastEditorUserId` (`LastEditorUserId`),
  KEY `ParentId` (`ParentId`),
  CONSTRAINT `posts_ibfk_1` FOREIGN KEY (`PostTypeId`) REFERENCES `posttypes` (`PostTypeId`)
) ENGINE=InnoDB;

8
সত্যি? আপনার যদি এক টন এন্ট্রি থাকে তবে কী হবে? উদাহরণস্বরূপ, আপনি যদি ডাব্লু / ইন-হাউস সংস্করণ নিয়ন্ত্রণের সাথে কাজ করছেন, বলুন এবং আপনার প্রতি ফাইলের জন্য এক টন সংস্করণ রয়েছে, এতে যোগদানের ফলাফলটি বিশাল হবে। আপনি কি কখনও এইটির সাথে সাবকিয়ার পদ্ধতিটি বেঞ্চমার্ক করেছেন? কোনটি জিতবে তা জানার জন্য আমি বেশ কৌতূহলী, তবে আপনাকে জিজ্ঞাসা না করার মতো উত্সাহী এখনও নয়।
এরিক 18 ই

2
কিছু পরীক্ষাও করেছেন। একটি ছোট টেবিলে (~ 300k রেকর্ডস, ~ 190k গ্রুপ, এত বড় গ্রুপ বা কিছুই নয়), কোয়েরিগুলি (8 সেকেন্ডে প্রতিটি) বেঁধে রাখা হয়েছে।
এরিক

1
@ বিলকারভিন: মেটা.স্ট্যাকেক্সেঞ্জাওয়েজ / প্রশ্ন / ১২৩০১17 , বিশেষত অ্যাডাম র্যাকিসের উত্তরের নীচের মন্তব্যগুলি দেখুন। আপনি যদি নতুন প্রশ্নের উত্তরটি পুনরায় দাবি করতে চান তবে আমাকে জানান Let
রবার্ট হার্ভে

3
@ টিম, না, <=যদি আপনার অ-অনন্য কলাম থাকে তবে সাহায্য করবে না। টাইব্রেকার হিসাবে আপনাকে অবশ্যই একটি অনন্য কলাম ব্যবহার করতে হবে।
বিল কারভিন 7

2
সারিগুলির সংখ্যা বাড়ার সাথে বা গ্রুপগুলি বড় হওয়ার সাথে সাথে কর্মক্ষমতাটি তত্পর হয়ে পড়ে। উদাহরণস্বরূপ 5 টি তারিখের সমন্বিত একটি গোষ্ঠী 4 + 3 + 2 + 1 + 1 = 11 টি সারি বাম দিক দিয়ে যোগ করবে যার মধ্যে একটি সারির শেষে ফিল্টার করা হবে। দলবদ্ধ ফলাফলের সাথে যোগদানের পারফরম্যান্স প্রায় লিনিয়ার। আপনার পরীক্ষাগুলি ত্রুটিযুক্ত দেখায়।
সালমান এ

145

ইউপিডি: 2017-03-31 , মাইএসকিউএল এর 5.7.5 সংস্করণটি কেবলমাত্র ডিফল্টরূপে কেবলমাত্র_এইফএলএলআল_গ্রোপ_বিওয়াই স্যুইচটিকে সক্ষম করেছে (সুতরাং, কোয়েরিগুলির দ্বারা অ-নিরস্ত্রীক গ্রোপ অক্ষম হয়ে গেছে)। তদুপরি, তারা বাস্তবায়নের মাধ্যমে গ্রুপ আপডেট করেছে এবং অক্ষম স্যুইচ দিয়েও সমাধানটি আশানুরূপভাবে কাজ করতে পারে না। একটি পরীক্ষা করা প্রয়োজন।

গ্রুপের মধ্যে আইটেমের গণনা না হলেও ছোট হয়ে গেলে উপরের কার্বিনের সমাধানটি ঠিকঠাক কাজ করে, তবে গ্রুপগুলি বরং বড় হলে ক্যোয়ারীর কার্যকারিতা খারাপ হয়ে যায়, কারণ সমাধানটি n*n/2 + n/2কেবলমাত্র সম্পর্কে প্রয়োজনIS NULL তুলনা করা প্রয়োজন।

আমি দলগুলির 18684446সাথে সারির একটি InnoDB টেবিলটিতে আমার পরীক্ষা করেছিলাম made 1182সারণীতে কার্যকরী পরীক্ষার জন্য পরীক্ষামূলক ফলাফল রয়েছে এবং এতে (test_id, request_id)প্রাথমিক কী রয়েছে। সুতরাং, test_idএকটি গ্রুপ এবং আমি request_idপ্রত্যেকের জন্য সর্বশেষটি অনুসন্ধান করছিলাম test_id

বিলের সমাধান ইতিমধ্যে আমার ডেল ই 4310 তে বেশ কয়েক ঘন্টা ধরে চলছে এবং আমি জানি না কখন এটি শেষ হতে চলেছে যদিও এটি একটি কভারেজ সূচকে কাজ করে (অতএব) using index এক্সপ্ল্যানে)।

আমার কাছে আরও কয়েকটি সমাধান রয়েছে যা একই ধারণার উপর ভিত্তি করে:

  • যদি অন্তর্নিহিত সূচকটি বিটিআরই সূচক হয় (যা সাধারণত এটি হয়) তবে বৃহত্তম (group_id, item_value)জুটি প্রতিটিটির মধ্যে শেষ মান হয় group_id, এটি প্রতিটিটির জন্য প্রথমgroup_id আমরা যদি সূচকে অবতরণ করে চলি তবে ;
  • যদি আমরা একটি সূচক দ্বারা আওতাভুক্ত মানগুলি পড়ি, মানগুলি সূচকের ক্রমে পাঠ করা হয়;
  • প্রতিটি সূচীতে অন্তর্ভুক্তভাবে প্রাথমিক কী কলামগুলি এতে যুক্ত হয় (এটি প্রাথমিক কীটি কভারেজ সূচকে থাকে)। নীচের সমাধানগুলিতে আমি সরাসরি প্রাথমিক কীটিতে পরিচালনা করি, আপনার ক্ষেত্রে আপনাকে ফলাফলের জন্য প্রাথমিক কী কলামগুলি যুক্ত করতে হবে।
  • অনেক ক্ষেত্রে একটি সাবকোয়রিতে প্রয়োজনীয় ক্রমে প্রয়োজনীয় সারি আইডি সংগ্রহ করা এবং আইডিতে সাবকোয়ারির ফলাফলটিতে যোগ দেওয়া অনেক সস্তা। যেহেতু সাবকিউরি ফলাফলের প্রতিটি সারিটির জন্য মাইএসকিউএলকে প্রাথমিক কীটির ভিত্তিতে একটি একক আনার প্রয়োজন হবে, তাই সাবকিউরিটি প্রথমে জোনে যুক্ত করা হবে এবং সারিগুলি সাবকিউরিতে আইডির ক্রম অনুসারে আউটপুট হবে (যদি আমরা স্পষ্টত অর্ডার বাদ দিই) যোগদানের জন্য)

3 টি মাইএসকিউএল সূচকগুলি ব্যবহার করে কিছু বিবরণ বোঝার জন্য একটি দুর্দান্ত নিবন্ধ।

সমাধান ঘ

এটি এক অবিশ্বাস্যরূপে দ্রুত, এটি আমার 18 এম + সারিগুলিতে 0,8 সেকেন্ড সময় নেয়:

SELECT test_id, MAX(request_id) AS request_id
FROM testresults
GROUP BY test_id DESC;

আপনি যদি আদেশটিকে এএসসিতে পরিবর্তন করতে চান, এটি সাবকিউরিতে রাখুন, কেবলমাত্র আইডিকে ফিরিয়ে দিন এবং বাকী কলামগুলিতে যোগদানের জন্য সাবকিউরি হিসাবে এটি ব্যবহার করুন:

SELECT test_id, request_id
FROM (
    SELECT test_id, MAX(request_id) AS request_id
    FROM testresults
    GROUP BY test_id DESC) as ids
ORDER BY test_id;

এটি আমার ডেটাতে প্রায় 1,2 সেকেন্ড নেয়।

সমাধান 2

আমার টেবিলে প্রায় 19 সেকেন্ড সময় লাগে এমন আরও একটি সমাধান এখানে দেওয়া হয়েছে:

SELECT test_id, request_id
FROM testresults, (SELECT @group:=NULL) as init
WHERE IF(IFNULL(@group, -1)=@group:=test_id, 0, 1)
ORDER BY test_id DESC, request_id DESC

এটি নিম্নোক্ত ক্রমে পরীক্ষাগুলিও প্রদান করে। এটি সম্পূর্ণ ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে।

ক্যোয়ারির অসুবিধা হ'ল এর ফলাফল ক্যোয়ারী ক্যাশে ক্যাশে করা যায় না।


দয়া করে আপনার টেবিলগুলির একটি ডাম্পের সাথে লিঙ্ক করুন যাতে লোকেরা তাদের প্ল্যাটফর্মে এটি পরীক্ষা করতে পারে।
পেসারিয়ার

3
সমাধান 1 কাজ করতে পারে না, আপনি দফা অনুসারে গ্রুপে না রেখে রিকোয়েস্ট_আইডি নির্বাচন করতে পারবেন না,

2
@ জিআই, এই উত্তরটি 5 বছরের পুরানো। মাইএসকিউএল 5.7.5 পর্যন্ত ONLY_FULL_GROUP_BY ডিফল্টরূপে নিষ্ক্রিয় করা হয় এবং এই সমাধান বাক্সের বাইরে কাজ dev.mysql.com/doc/relnotes/mysql/5.7/en/... । এখন আমি নিশ্চিত নই যে আপনি যখন মোডটি অক্ষম করবেন তখন সমাধানটি এখনও কার্যকর হয় কিনা, কারণ গ্রুপের মাধ্যমে বাস্তবায়ন পরিবর্তন করা হয়েছে।
newtover

আপনি যদি প্রথম সমাধানটিতে এএসসি চেয়েছিলেন, আপনি ম্যাক্সকে এমআইএন-এ পরিণত করেন তবে কি এটি কার্যকর হবে?
জিন

@ জিনজিরায়েল, আপনার প্রতিটি গ্রুপের শীর্ষে এমআইএন রয়েছে (এটি কভারিং সূচীর ক্রম): SELECT test_id, request_id FROM testresults GROUP BY test_id;প্রতিটি পরীক্ষার_আইডির জন্য সর্বনিম্ন রিকোয়েস্ট_আইডি ফিরিয়ে দেবে।
newtover

101

সঠিক দলবদ্ধকরণ ফিরিয়ে দিতে আপনার সাবকিউরিটি ব্যবহার করুন , কারণ আপনি সেখানে অর্ধেক হয়ে গেছেন

এটা চেষ্টা কর:

select
    a.*
from
    messages a
    inner join 
        (select name, max(id) as maxid from messages group by name) as b on
        a.id = b.maxid

যদি এটি না হয় তবে idআপনি সর্বোচ্চটি চান:

select
    a.*
from
    messages a
    inner join 
        (select name, max(other_col) as other_col 
         from messages group by name) as b on
        a.name = b.name
        and a.other_col = b.other_col

এইভাবে, আপনি আপনার সাবকিউরিতে সম্পর্কিত সম্পর্কযুক্ত সাবকোয়ারিগুলি এবং / অথবা ক্রম এড়াতে পারবেন যা খুব ধীর / অদক্ষ হয়ে থাকে।


1
এর সাথে সমাধানের জন্য একটি সতর্কতা নোট করুন other_col: যদি এই কলামটি অনন্য না হয় তবে আপনি যদি এটির সাথে nameটাই করেন তবে আপনি একই সাথে একাধিক রেকর্ড ফিরে পেতে পারেন max(other_col)। আমি এই পোস্টটি পেয়েছি যা আমার প্রয়োজনের জন্য একটি সমাধান বর্ণনা করে, যেখানে আমার প্রতি প্রতি এক রেকর্ড প্রয়োজন name
এরিক সিমন্তন

কিছু পরিস্থিতিতে আপনি কেবল এই সমাধানটি ব্যবহার করতে পারেন তবে গ্রহণযোগ্যটিকে অন্ট করতে পারেন।
tom10271

আমার অভিজ্ঞতায়, এটি সম্পূর্ণ জঘন্য বার্তাগুলি টেবিলকে গোষ্ঠীভুক্ত করছে যা ধীর / অদক্ষ হতে থাকে! অন্য কথায়, মনে রাখবেন যে সাবকিউয়ের একটি সম্পূর্ণ টেবিল স্ক্যান প্রয়োজন, এবং বুট করার জন্য এটিতে একটি গ্রুপিং করা হয় ... যতক্ষণ না আপনার অপ্টিমাইজারটি এমন কিছু না করে যা আমার নয়। সুতরাং এই সমাধানটি মেমরির পুরো টেবিলটি ধরে রাখার উপর নির্ভর করে।
টিমো

এগুলি থেকে উপকার পাবেন INDEX(name, id)এবংINDEX(name, other_col)
রিক জেমস

55

আমি একটি পৃথক সমাধানে পৌঁছেছি, যা প্রতিটি গ্রুপের মধ্যে শেষ পোস্টের জন্য আইডিগুলি পেতে হয়, তারপরে বার্তাগুলির সারণি থেকে প্রথম প্রশ্নের সাথে ফলাফলটি ব্যবহার করে বিন্যাসের পক্ষে যুক্তি হিসাবে নির্বাচন করুন WHERE x IN:

SELECT id, name, other_columns
FROM messages
WHERE id IN (
    SELECT MAX(id)
    FROM messages
    GROUP BY name
);

অন্যান্য সমাধানগুলির তুলনায় এটি কীভাবে সম্পাদন করে তা আমি জানি না, তবে এটি আমার টেবিলের জন্য 3+ মিলিয়ন সারি দিয়ে দর্শনীয়ভাবে কাজ করেছিল। (1200+ ফলাফল সহ 4 দ্বিতীয় কার্যকর)

এটি মাইএসকিউএল এবং এসকিউএল সার্ভার উভয় ক্ষেত্রেই কাজ করা উচিত।


কেবলমাত্র নিশ্চিত হয়ে নিন যে আপনার নাম (নাম, আইডি) রয়েছে।
স্যামুয়েল -স্লুন্ড

1
অনেক ভালো স্ব যোগদান করে যে
anwerj

আমি আপনার কাছ থেকে এমন কিছু শিখেছি যা একটি ভাল কাজ এবং এই কোয়েরিটি দ্রুত
হামফ্রে

33

সাব কোয়েরি ফিডল লিংক দ্বারা সমাধান

select * from messages where id in
(select max(id) from messages group by Name)

সমাধান কন্ডিশনের সাথে যোগ করুন ফিডল লিঙ্ক

select m1.* from messages m1 
left outer join messages m2 
on ( m1.id<m2.id and m1.name=m2.name )
where m2.id is null

এই পোস্টের কারণটি কেবল ফিডল লিঙ্ক দেওয়া। একই এসকিউএল ইতিমধ্যে অন্যান্য উত্তরে সরবরাহ করা হয়েছে।


1
@ আলেকজান্ডারসুরফেল mysql5.5 এখন ফ্রিডিতে উপলভ্য নয়, এটি ব্যবহার করে ফিডাল লিঙ্ক তৈরি করা হয়েছিল। এখন একটি দিন ফিডল mysql5.6 সমর্থন করে, আমি ডাটাবেসটি mysql 5.6 এ পরিবর্তন করেছি এবং আমি স্কিমা তৈরি করতে এবং স্ক্যালিএল চালাতে সক্ষম।
বিপণি

8

উল্লেখযোগ্য গতির সাথে একটি পন্থা নিম্নরূপ।

SELECT * 
FROM messages a
WHERE Id = (SELECT MAX(Id) FROM messages WHERE a.Name = Name)

ফলাফল

Id  Name    Other_Columns
3   A   A_data_3
5   B   B_data_2
6   C   C_data_1

এটি ধরে নেওয়া idআপনার যেভাবে প্রয়োজন তা অর্ডার করা হয়েছে। সাধারণ ক্ষেত্রে আরও কিছু কলামের প্রয়োজন হয়।
রিক জেমস

6

এখানে দুটি পরামর্শ দেওয়া হল। প্রথমত, যদি মাইএসকিএল ROW_NUMBER () সমর্থন করে তবে এটি খুব সহজ:

WITH Ranked AS (
  SELECT Id, Name, OtherColumns,
    ROW_NUMBER() OVER (
      PARTITION BY Name
      ORDER BY Id DESC
    ) AS rk
  FROM messages
)
  SELECT Id, Name, OtherColumns
  FROM messages
  WHERE rk = 1;

আমি "শেষ" দ্বারা ধরে নিচ্ছি আপনি আইডির অর্ডারে সর্বশেষ বোঝাচ্ছেন। যদি তা না হয় তবে সেই অনুযায়ী ROW_NUMBER () উইন্ডোর অর্ডার বাই ক্লজটি পরিবর্তন করুন। যদি ROW_NUMBER () উপলব্ধ না হয় তবে এটি অন্য একটি সমাধান:

দ্বিতীয়ত, যদি তা না হয় তবে এটি প্রায়শই এগিয়ে যাওয়ার ভাল উপায়:

SELECT
  Id, Name, OtherColumns
FROM messages
WHERE NOT EXISTS (
  SELECT * FROM messages as M2
  WHERE M2.Name = messages.Name
  AND M2.Id > messages.Id
)

অন্য কথায়, একই নামের সাথে কোনও পরবর্তী-আইডি বার্তা নেই এমন বার্তাগুলি নির্বাচন করুন।


8
মাইএসকিউএল ROW_NUMBER () বা সিটিই'র সমর্থন করে না।
বিল কারভিন

1
মাইএসকিউএল 8.0 (এবং মারিয়াডিবি 10.2) এখন সমর্থন করে ROW_NUMBER()এবং সিটিইগুলি।
রিক জেমস

6

আমি এখনও বড় ডিবি দিয়ে পরীক্ষা করিনি তবে আমি মনে করি এটি টেবিলগুলিতে যোগদানের চেয়ে দ্রুততর হতে পারে:

SELECT *, Max(Id) FROM messages GROUP BY Name

14
এটি নির্বিচারে ডেটা ফেরত দেয়। অন্য কথায় এখানে ফিরে আসা কলামগুলি ম্যাক্স (আইডি) সহ রেকর্ড হতে পারে না।
ক্ষতি করুন

যেখানে শর্তের সাথে রেকর্ডের সেট থেকে সর্বোচ্চ আইডি নির্বাচন করা কার্যকর: "যেখানে Pn = '" + পিএন + "" উত্পাদন থেকে সর্বাধিক আইডি নির্বাচন করুন "এটি একই পিএন এর সাথে রেকর্ডের সেট থেকে সর্বোচ্চ আইডি প্রদান করে c ফলাফল পেতে পাঠক.গেটস্ট্রিং (0) ব্যবহার করুন
নিকোলা

5

GROUP_CONCATঅর্ডার দিয়ে সর্বশেষ সম্পর্কিত রেকর্ডটি পেতে SUBSTRING_INDEXএবং তালিকা থেকে একটি রেকর্ড বাছাই করার আরও একটি উপায় এখানে

SELECT 
  `Id`,
  `Name`,
  SUBSTRING_INDEX(
    GROUP_CONCAT(
      `Other_Columns` 
      ORDER BY `Id` DESC 
      SEPARATOR '||'
    ),
    '||',
    1
  ) Other_Columns 
FROM
  messages 
GROUP BY `Name` 

উপরের ক্যোয়ারী সমস্ত Other_Columnsএকই Nameগ্রুপে থাকবে এবং ব্যবহারের ক্ষেত্রে আমার ব্যবহৃত ক্ষেত্রে বিভক্তকারীটির সাথে উত্থাপিত ক্রমের সাথে একটি নির্দিষ্ট গোষ্ঠীতে ORDER BY id DESCযোগ দেবে , এই তালিকার উপরের Other_Columnsব্যবহারটি প্রথমটিকে বেছে নেবে||SUBSTRING_INDEX

ফিডল ডেমো


আপনি কয়টি group_concat_max_lenসারি পরিচালনা করতে পারবেন তা সীমাবদ্ধ রাখুন aware
রিক জেমস

5

স্পষ্টতই একই ফলাফল পাওয়ার বিভিন্ন উপায় রয়েছে, আপনার প্রশ্নটি মনে হয় মাইএসকিউএলে প্রতিটি গ্রুপে শেষ ফলাফল পাওয়ার কার্যকর উপায় কোনটি। আপনি যদি প্রচুর পরিমাণে ডেটা নিয়ে কাজ করছেন এবং ধরে নিচ্ছেন যে আপনি মাইএসকিউএল এর সর্বশেষতম সংস্করণ (যেমন 5..7.২১ এবং ৮.০.৪-আরসি) সহ ইনোডিবি ব্যবহার করছেন তবে এটি করার কোনও কার্যকর উপায় নাও থাকতে পারে।

আমাদের মাঝে মাঝে 60 মিলিয়নেরও বেশি সারি সহ টেবিলগুলি দিয়ে এটি করা দরকার।

এই উদাহরণগুলির জন্য আমি প্রায় 1.5 মিলিয়ন সারি সহ ডেটা ব্যবহার করব যেখানে কোয়েরিতে ডেটাতে সমস্ত গোষ্ঠীর জন্য ফলাফলগুলি খুঁজে পাওয়া দরকার। আমাদের প্রকৃত ক্ষেত্রে আমাদের প্রায়শই প্রায় ২,০০০ গ্রুপ থেকে ডেটা ফিরিয়ে নেওয়া দরকার (যা অনুমানের সাথে খুব বেশি ডেটা পরীক্ষা করার প্রয়োজন হয় না)।

আমি নিম্নলিখিত সারণি ব্যবহার করব:

CREATE TABLE temperature(
  id INT UNSIGNED NOT NULL AUTO_INCREMENT, 
  groupID INT UNSIGNED NOT NULL, 
  recordedTimestamp TIMESTAMP NOT NULL, 
  recordedValue INT NOT NULL,
  INDEX groupIndex(groupID, recordedTimestamp), 
  PRIMARY KEY (id)
);

CREATE TEMPORARY TABLE selected_group(id INT UNSIGNED NOT NULL, PRIMARY KEY(id)); 

তাপমাত্রা টেবিলটি প্রায় 1.5 মিলিয়ন এলোমেলো রেকর্ড এবং 100 টি বিভিন্ন গোষ্ঠী সহ জনবহুল। নির্বাচিত_গোষ্ঠীটি এই 100 টি গ্রুপের সাথে জনবহুল (আমাদের ক্ষেত্রে এটি সাধারণত সমস্ত দলের জন্য 20% এর চেয়ে কম হবে)।

এই ডেটাটি এলোমেলো হওয়ার অর্থ এটির অর্থ হ'ল একাধিক সারিতে একই রেকর্ডড টাইমস্ট্যাম্প থাকতে পারে। আমরা যা চাই তা হ'ল প্রতিটি গ্রুপের জন্য শেষ রেকর্ডডটাইমস্ট্যাম্প সহ গ্রুপআইডির ক্রম অনুসারে নির্বাচিত সমস্ত গ্রুপের একটি তালিকা পাওয়া, এবং যদি একই গ্রুপের মতো একাধিক সারি সারি থাকে তবে সেই সারিগুলির শেষ ম্যাচিং আইডি।

যদি হাইপোথিটিক্যালি মাইএসকিউএলের একটি শেষ () ফাংশন থাকে যা একটি বিশেষ অর্ডার দ্বারা একটি বিশেষ আদেশের মাধ্যমে শেষ সারি থেকে মানগুলি ফিরিয়ে দেয় তবে আমরা কেবল এটি করতে পারি:

SELECT 
  last(t1.id) AS id, 
  t1.groupID, 
  last(t1.recordedTimestamp) AS recordedTimestamp, 
  last(t1.recordedValue) AS recordedValue
FROM selected_group g
INNER JOIN temperature t1 ON t1.groupID = g.id
ORDER BY t1.recordedTimestamp, t1.id
GROUP BY t1.groupID;

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

তবে মাইএসকিউএল এর এটি নেই তাই আসুন এটির কী রয়েছে তার বিভিন্ন ধারণাটি দেখুন এবং প্রমাণ করুন যে এগুলির কোনওটিই দক্ষ নয়।

উদাহরণ 1

SELECT t1.id, t1.groupID, t1.recordedTimestamp, t1.recordedValue
FROM selected_group g
INNER JOIN temperature t1 ON t1.id = (
  SELECT t2.id
  FROM temperature t2 
  WHERE t2.groupID = g.id
  ORDER BY t2.recordedTimestamp DESC, t2.id DESC
  LIMIT 1
);

এটি 3,009,254 সারি পরীক্ষা করেছে এবং 5.7.21 এ 85 0.859 সেকেন্ড সময় নিয়েছে এবং 8.0.4-আর সি তে সামান্য লম্বা হয়েছে

উদাহরণ 2

SELECT t1.id, t1.groupID, t1.recordedTimestamp, t1.recordedValue 
FROM temperature t1
INNER JOIN ( 
  SELECT max(t2.id) AS id   
  FROM temperature t2
  INNER JOIN (
    SELECT t3.groupID, max(t3.recordedTimestamp) AS recordedTimestamp
    FROM selected_group g
    INNER JOIN temperature t3 ON t3.groupID = g.id
    GROUP BY t3.groupID
  ) t4 ON t4.groupID = t2.groupID AND t4.recordedTimestamp = t2.recordedTimestamp
  GROUP BY t2.groupID
) t5 ON t5.id = t1.id;

এটি 1,505,331 সারি পরীক্ষা করেছে এবং 5.7.21 এ 25 1.25 সেকেন্ড নিয়েছে এবং 8.0.4-আরসি তে সামান্য দীর্ঘ

উদাহরণ 3

SELECT t1.id, t1.groupID, t1.recordedTimestamp, t1.recordedValue 
FROM temperature t1
WHERE t1.id IN ( 
  SELECT max(t2.id) AS id   
  FROM temperature t2
  INNER JOIN (
    SELECT t3.groupID, max(t3.recordedTimestamp) AS recordedTimestamp
    FROM selected_group g
    INNER JOIN temperature t3 ON t3.groupID = g.id
    GROUP BY t3.groupID
  ) t4 ON t4.groupID = t2.groupID AND t4.recordedTimestamp = t2.recordedTimestamp
  GROUP BY t2.groupID
)
ORDER BY t1.groupID;

এটি 3,009,685 সারি পরীক্ষা করেছে এবং 5.7.21 এ 95 1.95 সেকেন্ড সময় নিয়েছে এবং 8.0.4-আর সি তে সামান্য লম্বা হয়েছে

উদাহরণ 4

SELECT t1.id, t1.groupID, t1.recordedTimestamp, t1.recordedValue
FROM selected_group g
INNER JOIN temperature t1 ON t1.id = (
  SELECT max(t2.id)
  FROM temperature t2 
  WHERE t2.groupID = g.id AND t2.recordedTimestamp = (
      SELECT max(t3.recordedTimestamp)
      FROM temperature t3 
      WHERE t3.groupID = g.id
    )
);

এটি 6,137,810 সারি পরীক্ষা করেছে এবং 5.7.21 এ ~ 2.2 সেকেন্ড সময় নিয়েছে এবং 8.0.4-আরসি তে কিছুটা লম্বা করেছে

উদাহরণ 5

SELECT t1.id, t1.groupID, t1.recordedTimestamp, t1.recordedValue
FROM (
  SELECT 
    t2.id, 
    t2.groupID, 
    t2.recordedTimestamp, 
    t2.recordedValue, 
    row_number() OVER (
      PARTITION BY t2.groupID ORDER BY t2.recordedTimestamp DESC, t2.id DESC
    ) AS rowNumber
  FROM selected_group g 
  INNER JOIN temperature t2 ON t2.groupID = g.id
) t1 WHERE t1.rowNumber = 1;

এটি 6,017,808 সারি পরীক্ষা করেছে এবং 8.0.4-rc এ ~ 4.2 সেকেন্ড নিয়েছে

উদাহরণ 6

SELECT t1.id, t1.groupID, t1.recordedTimestamp, t1.recordedValue 
FROM (
  SELECT 
    last_value(t2.id) OVER w AS id, 
    t2.groupID, 
    last_value(t2.recordedTimestamp) OVER w AS recordedTimestamp, 
    last_value(t2.recordedValue) OVER w AS recordedValue
  FROM selected_group g
  INNER JOIN temperature t2 ON t2.groupID = g.id
  WINDOW w AS (
    PARTITION BY t2.groupID 
    ORDER BY t2.recordedTimestamp, t2.id 
    RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
  )
) t1
GROUP BY t1.groupID;

এটি 6,017,908 সারি পরীক্ষা করেছে এবং 8.0.4-rc এ 17.5 সেকেন্ড সময় নিয়েছে

উদাহরণ 7

SELECT t1.id, t1.groupID, t1.recordedTimestamp, t1.recordedValue 
FROM selected_group g
INNER JOIN temperature t1 ON t1.groupID = g.id
LEFT JOIN temperature t2 
  ON t2.groupID = g.id 
  AND (
    t2.recordedTimestamp > t1.recordedTimestamp 
    OR (t2.recordedTimestamp = t1.recordedTimestamp AND t2.id > t1.id)
  )
WHERE t2.id IS NULL
ORDER BY t1.groupID;

এইটি চিরকালের জন্য নিচ্ছে তাই আমাকে এটি মেরে ফেলতে হয়েছিল।


এটি একটি ভিন্ন সমস্যা। এবং সমাধানটি একটি বিশাল ইউনিয়ন সমস্ত কোয়েরি।
পল স্পিগেল

@ পোলস্প্পেইগেল আমি অনুমান করি আপনি সমস্ত বিশাল ইউনিয়ন সম্পর্কে মজা করছেন। নির্বাচিত সমস্ত গ্রুপকে আগে থেকেই জানা থাকা দরকার ছিল এবং এটির সাথে মিলিয়ে 2,000 টি নির্বাচিত গ্রুপ যা অবিশ্বাস্যরকম বিশাল প্রশ্ন হবে, এটি উপরের দ্রুততম উদাহরণের চেয়ে আরও খারাপ সম্পাদন করবে, তাই না, এটি একটি হবে না সমাধান।
ইউসোফ

আমি একেবারে সিরিয়াস। অতীতে আমি কয়েক শতাধিক গ্রুপ নিয়ে পরীক্ষা করেছি tested যখন আপনাকে বড় গ্রুপগুলিতে সম্পর্কগুলি পরিচালনা করতে হবে তখন মাইএসকিউএল-এ ইউনিয়ন সবই একটি সর্বোত্তম প্রয়োগের পরিকল্পনাকে বাধ্য করার একমাত্র উপায়। SELECT DISTINCT(groupID)দ্রুত এবং এটি আপনাকে এমন ডেটা দেবে যা আপনাকে এ জাতীয় একটি কোয়েরি তৈরি করতে হবে। আপনি যতক্ষণ না অতিক্রম না করে ক্যোয়ারী আকারটি max_allowed_packetদিয়ে ঠিকঠাক হওয়া উচিত, এটি মাইএসকিউএল 5.7-এ 4MB এর ডিফল্ট।
পল স্পিগেল

5

আমরা রেকর্ড অনুসারে একটি গ্রুপ বাই রেকর্ডে মাইএসকিউএল কীভাবে ব্যবহার করতে পারি তা আমরা লক্ষ্য করব। উদাহরণস্বরূপ আপনার যদি পোস্টের এই ফলাফল সেট থাকে।

id category_id post_title

1 1 Title 1

2 1 Title 2

3 1 Title 3

4 2 Title 4

5 2 Title 5

6 3 Title 6

আমি প্রতিটি বিভাগে সর্বশেষ পোস্ট পেতে সক্ষম হতে চাই যা শিরোনাম 3, শিরোনাম 5 এবং শিরোনাম 6। বিভাগ দ্বারা পোস্টগুলি পেতে আপনি কিবোর্ড দ্বারা মাইএসকিউএল গ্রুপ ব্যবহার করবেন।

select * from posts group by category_id

তবে আমরা এই ক্যোয়ারী থেকে ফিরে আসা ফলাফলগুলি।

id category_id post_title

1 1 Title 1

4 2 Title 4

6 3 Title 6

গোষ্ঠীটি সর্বদা ফলাফল সেটে গ্রুপে প্রথম রেকর্ডটি ফিরিয়ে দেবে।

SELECT id, category_id, post_title FROM posts WHERE id IN ( SELECT MAX(id) FROM posts GROUP BY category_id );

এটি প্রতিটি গ্রুপের সর্বোচ্চ আইডি সহ পোস্টগুলি ফিরিয়ে দেবে।

id category_id post_title

3 1 Title 3

5 2 Title 5

6 3 Title 6

রেফারেন্স এখানে ক্লিক করুন


4
SELECT 
  column1,
  column2 
FROM
  table_name 
WHERE id IN 
  (SELECT 
    MAX(id) 
  FROM
    table_name 
  GROUP BY column1) 
ORDER BY column1 ;

আপনি কি নিজের উত্তরে কিছুটা ব্যাখ্যা করতে পারবেন? আপনার প্রশ্নটি বিজয়ের মূল প্রশ্নের সাথে কেন পছন্দনীয়?
janfoeh

4

এখানে আমার সমাধান:

SELECT 
  DISTINCT NAME,
  MAX(MESSAGES) OVER(PARTITION BY NAME) MESSAGES 
FROM MESSAGE;

এটি নাম অনুসারে সর্বশেষ বার্তাটি দেয় না। এবং এটি কেবল একটি অত্যধিক জটিল সংস্করণ SELECT NAME, MAX(MESSAGES) MESSAGES FROM MESSAGE GROUP BY NAME
পল স্পিগেল

তদুপরি, এই সূত্রটি চূড়ান্তভাবে অক্ষম।
রিক জেমস

3

এটা চেষ্টা কর:

SELECT jos_categories.title AS name,
       joined .catid,
       joined .title,
       joined .introtext
FROM   jos_categories
       INNER JOIN (SELECT *
                   FROM   (SELECT `title`,
                                  catid,
                                  `created`,
                                  introtext
                           FROM   `jos_content`
                           WHERE  `sectionid` = 6
                           ORDER  BY `id` DESC) AS yes
                   GROUP  BY `yes`.`catid` DESC
                   ORDER  BY `yes`.`created` DESC) AS joined
         ON( joined.catid = jos_categories.id )  

3

হাই @Vijay দেব আপনার টেবিল যদি বার্তা ধারণ করে আইডি যা পরে স্বয়ং বৃদ্ধি প্রাথমিক চাবিকাঠি প্রাথমিক কী আপনার প্রশ্নের নীচের হিসাবে পড়া উচিত সর্বশেষ রেকর্ড ভিত্তিতে আনতে:

SELECT m1.* FROM messages m1 INNER JOIN (SELECT max(Id) as lastmsgId FROM messages GROUP BY Name) m2 ON m1.Id=m2.lastmsgId

আমি খুঁজে পাওয়া এই
দ্রুততমটি

3

আপনি এখান থেকেও ভিউ নিতে পারেন।

http://sqlfiddle.com/#!9/ef42b/9

প্রথম সমাধান

SELECT d1.ID,Name,City FROM Demo_User d1
INNER JOIN
(SELECT MAX(ID) AS ID FROM Demo_User GROUP By NAME) AS P ON (d1.ID=P.ID);

দ্বিতীয় সমাধান

SELECT * FROM (SELECT * FROM Demo_User ORDER BY ID DESC) AS T GROUP BY NAME ;

3
SELECT * FROM table_name WHERE primary_key IN (SELECT MAX(primary_key) FROM table_name GROUP BY column_name )


2

কোনও টেবিলের নকল মুছতে এই পদ্ধতিটি ব্যবহার করার কোনও উপায় আছে কি? ফলাফল সেটটি মূলত অনন্য রেকর্ডের সংগ্রহ, সুতরাং আমরা যদি ফলাফলের সেটে না থেকে সমস্ত রেকর্ড মুছতে পারি, তবে আমাদের কার্যকরভাবে কোনও নকল থাকবে না? আমি এটি চেষ্টা করেছিলাম তবে মাইএসকিউএল একটি 1093 ত্রুটি দিয়েছে।

DELETE FROM messages WHERE id NOT IN
 (SELECT m1.id  
 FROM messages m1 LEFT JOIN messages m2  
 ON (m1.name = m2.name AND m1.id < m2.id)  
 WHERE m2.id IS NULL)

টেম্প ভেরিয়েবলের আউটপুট সংরক্ষণ করার পরে নট ইন (টেম্প ভেরিয়েবল) থেকে মুছার কোনও উপায় কি আছে? @ বিল একটি খুব দরকারী সমাধানের জন্য ধন্যবাদ।

সম্পাদনা: ভাবুন আমি সমাধানটি পেয়েছি:

DROP TABLE IF EXISTS UniqueIDs; 
CREATE Temporary table UniqueIDs (id Int(11)); 

INSERT INTO UniqueIDs 
    (SELECT T1.ID FROM Table T1 LEFT JOIN Table T2 ON 
    (T1.Field1 = T2.Field1 AND T1.Field2 = T2.Field2 #Comparison Fields  
    AND T1.ID < T2.ID) 
    WHERE T2.ID IS NULL); 

DELETE FROM Table WHERE id NOT IN (SELECT ID FROM UniqueIDs);

2

নীচের ক্যোয়ারী আপনার প্রশ্ন অনুসারে কাজ করবে।

SELECT M1.* 
FROM MESSAGES M1,
(
 SELECT SUBSTR(Others_data,1,2),MAX(Others_data) AS Max_Others_data
 FROM MESSAGES
 GROUP BY 1
) M2
WHERE M1.Others_data = M2.Max_Others_data
ORDER BY Others_data;

2

আপনি যদি প্রতিটিটির জন্য শেষ সারিটি চান Nameতবে আপনি প্রতিটি সারি গোষ্ঠীকে একটি সারি নম্বর দিতে পারেন Nameএবং আদেশ দিয়েId অবরোহী।

প্রশ্ন

SELECT t1.Id, 
       t1.Name, 
       t1.Other_Columns
FROM 
(
     SELECT Id, 
            Name, 
            Other_Columns,
    (
        CASE Name WHEN @curA 
        THEN @curRow := @curRow + 1 
        ELSE @curRow := 1 AND @curA := Name END 
    ) + 1 AS rn 
    FROM messages t, 
    (SELECT @curRow := 0, @curA := '') r 
    ORDER BY Name,Id DESC 
)t1
WHERE t1.rn = 1
ORDER BY t1.Id;

এসকিউএল ফিডল


2

এটি সম্পর্কে:

SELECT DISTINCT ON (name) *
FROM messages
ORDER BY name, id DESC;

আমার অনুরূপ ইস্যু ছিল (পোস্টগ্র্যাস্কল শক্ত) এবং একটি 1 এম রেকর্ড টেবিলে। এই সমাধানটি বাম জোনের সাথে একটির উত্পাদিত 1.7s বনাম 44 সেকেন্ড নেয়। আমার ক্ষেত্রে আমাকে আপনার নাম ক্ষেত্রের নূতন মানগুলির তুলনায় ফিল্টার করতে হয়েছিল , যার ফলে 0.2 সেকেন্ডের চেয়ে আরও ভাল পারফরম্যান্স হতে পারে


1

পারফরম্যান্স যদি সত্যিই আপনার উদ্বেগ হয় তবে আপনি ডাকা টেবিলে একটি নতুন কলাম প্রবর্তন করতে পারেন IsLastInGroup বিআইটি প্রকারের ।

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

সুতরাং আপনার প্রশ্নের মতামতটি দেখতে পাবেন:

SELECT * FROM Messages WHERE IsLastInGroup = 1

মুডলে কিছু টেবিলের মতো একটি পতাকা কলাম রয়েছে।
লরেন্স


0

আপনি গণনা করে গ্রুপ করতে পারেন এবং গ্রুপের মতো শেষ আইটেমটি পেতে পারেন:

SELECT 
    user,
    COUNT(user) AS count,
    MAX(id) as last
FROM request 
GROUP BY user

0

ওরাকল ক্যোয়ারির নীচে আশা করি সহায়তা করতে পারে:

WITH Temp_table AS
(
    Select id, name, othercolumns, ROW_NUMBER() over (PARTITION BY name ORDER BY ID 
    desc)as rank from messages
)
Select id, name,othercolumns from Temp_table where rank=1

0

অন্য পদ্ধতি:

প্রতিটি প্রোগ্রামের সাথে সর্বাধিক এম 2_প্রাইস (1 টি প্রোগ্রামে এন বৈশিষ্ট্য) সহ উপযুক্তটি সন্ধান করুন:

select * from properties p
join (
    select max(m2_price) as max_price 
    from properties 
    group by program_id
) p2 on (p.program_id = p2.program_id)
having p.m2_price = max_price
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.