মাইএসকিউএল অর্ডার আগে গ্রুপ দ্বারা


243

এখানে প্রচুর অনুরূপ প্রশ্ন পাওয়া যাবে তবে আমি মনে করি না যে কোনও প্রশ্নের যথাযথ উত্তর দেওয়া উচিত।

আমি বর্তমানের সর্বাধিক জনপ্রিয় প্রশ্ন থেকে চালিয়ে যাব এবং যদি ঠিক থাকে তবে তাদের উদাহরণ ব্যবহার করব।

এই উদাহরণস্বরূপ কাজটি হ'ল ডাটাবেসের প্রতিটি লেখকের জন্য সর্বশেষতম পোস্ট get

উদাহরণ ক্যোয়ারী সর্বদা সর্বশেষতম পোস্টটি হিসাবে ফিরে আসে না হিসাবে অযৌক্তিক ফলাফল তৈরি করে।

SELECT wp_posts.* FROM wp_posts
    WHERE wp_posts.post_status='publish'
    AND wp_posts.post_type='post'
    GROUP BY wp_posts.post_author           
    ORDER BY wp_posts.post_date DESC

বর্তমান গৃহীত উত্তর হ'ল

SELECT
    wp_posts.*
FROM wp_posts
WHERE
    wp_posts.post_status='publish'
    AND wp_posts.post_type='post'
GROUP BY wp_posts.post_author
HAVING wp_posts.post_date = MAX(wp_posts.post_date) <- ONLY THE LAST POST FOR EACH AUTHOR
ORDER BY wp_posts.post_date DESC

দুর্ভাগ্যক্রমে এই উত্তরটি সরল এবং সাধারণ ভুল এবং অনেক ক্ষেত্রে অরজিনাল ক্যোয়ারির চেয়ে কম স্থিতিশীল ফলাফল উত্পন্ন করে।

আমার সেরা সমাধানটি ফর্মের একটি subquery ব্যবহার করা হয়

SELECT wp_posts.* FROM 
(
    SELECT * 
    FROM wp_posts
    ORDER BY wp_posts.post_date DESC
) AS wp_posts
WHERE wp_posts.post_status='publish'
AND wp_posts.post_type='post'
GROUP BY wp_posts.post_author 

আমার প্রশ্নটি তখন সাধারণ একটি: কোনও উপকোয়াকে অবলম্বন না করে গ্রুপিংয়ের আগে কি সারিগুলি অর্ডার করতে হবে?

সম্পাদনা : এই প্রশ্নটি অন্য একটি প্রশ্নের ধারাবাহিকতা ছিল এবং আমার পরিস্থিতির সুনির্দিষ্ট কিছুটা আলাদা। আপনি ধরে নিতে পারেন (এবং হওয়া উচিত) এমন একটি wp_posts.idও রয়েছে যা সেই নির্দিষ্ট পোস্টের জন্য একটি অনন্য সনাক্তকারী।


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

@ সিরুফো আপনি ঠিক বলেছেন, আমি আপনার জন্য একটি সম্পাদনা যুক্ত করেছি।
রব ফরেস্ট

There are plenty of similar questions to be found on here but I don't think that any answer the question adequately.এটাই অনুদানের জন্য।
অরব্বিটে হালকাতা রেস

@ লাইটনেসেসেসিন অরবিট, যদি বর্তমান প্রশ্নের ইতিমধ্যে একটি স্বীকৃত উত্তর থাকে যে আমার মতে ভুল, আপনি কী করার পরামর্শ দিচ্ছেন?
রব ফরেস্ট

1
আপনি কেন এমন কোনও উত্তর গ্রহণ করলেন যা উপকৌজন্য ব্যবহার করে - আপনি যখন প্রশ্নটি পরিষ্কারভাবে জিজ্ঞাসা করলেন তখন কেন আপনি অবাক হলেন? ”
টিভি-সি-15

উত্তর:


373

ORDER BYসাবকিউরিতে একটি ব্যবহার করা এই সমস্যার সর্বোত্তম সমাধান নয়।

max(post_date)লেখক দ্বারা প্রাপ্ত সর্বাধিক সমাধান হ'ল সর্বাধিক তারিখটি ফেরত দেওয়ার জন্য একটি সাবকোয়ারি ব্যবহার করা এবং তারপরে আপনার টেবিলে post_authorএবং সর্বাধিক তারিখের সাথে যুক্ত হওয়া।

সমাধানটি হওয়া উচিত:

SELECT p1.* 
FROM wp_posts p1
INNER JOIN
(
    SELECT max(post_date) MaxPostDate, post_author
    FROM wp_posts
    WHERE post_status='publish'
       AND post_type='post'
    GROUP BY post_author
) p2
  ON p1.post_author = p2.post_author
  AND p1.post_date = p2.MaxPostDate
WHERE p1.post_status='publish'
  AND p1.post_type='post'
order by p1.post_date desc

আপনার যদি নিম্নলিখিত নমুনা ডেটা থাকে:

CREATE TABLE wp_posts
    (`id` int, `title` varchar(6), `post_date` datetime, `post_author` varchar(3))
;

INSERT INTO wp_posts
    (`id`, `title`, `post_date`, `post_author`)
VALUES
    (1, 'Title1', '2013-01-01 00:00:00', 'Jim'),
    (2, 'Title2', '2013-02-01 00:00:00', 'Jim')
;

সাবকিউরিটি সর্বাধিক তারিখ এবং লেখককে ফিরিয়ে দিতে চলেছে:

MaxPostDate | Author
2/1/2013    | Jim

তারপরে যেহেতু আপনি সেই টেবিলে ফিরে যাচ্ছেন, উভয় মানেই আপনি সেই পোস্টের সম্পূর্ণ বিবরণ ফিরিয়ে আনবেন।

ডেমো সহ এসকিউএল ফিডল দেখুন ।

এই তথ্যটি সঠিকভাবে ফেরত দেওয়ার জন্য সাবকিউরিটি ব্যবহার সম্পর্কে আমার মন্তব্যগুলিতে প্রসারিত করুন।

মাইএসকিউএল GROUP BYআপনি SELECTতালিকায় অন্তর্ভুক্ত প্রতিটি কলামে আপনাকে জোর করে না । ফলস্বরূপ, যদি আপনি কেবল GROUP BYএকটি কলাম করেন তবে মোট 10 টি কলাম ফেরত দেন তবে কোনও গ্যারান্টি নেই যে অন্যান্য কলামের মানগুলি যা এতে post_authorরয়েছে returned কলামটি যদি কোনও GROUP BYমাইএসকিউএল না থাকে তবে কোন মানটি প্রদান করা উচিত তা চয়ন করে।

সমষ্টিগত ফাংশন সহ সাবকোয়ারি ব্যবহার করা গ্যারান্টি দেয় যে সঠিক লেখক এবং পোস্ট প্রতিবার ফিরে আসবে।

সাইড নোট হিসাবে, যখন মাইএসকিউএল আপনাকে ORDER BYসাবকিউরিতে একটি ব্যবহার করার অনুমতি দেয় এবং আপনাকে তালিকার GROUP BYপ্রতিটি কলামে এটি প্রয়োগ করার SELECTঅনুমতি দেয় তবে এসকিউএল সার্ভার সহ অন্যান্য ডাটাবেসে এই আচরণের অনুমতি নেই।


4
আমি দেখছি আপনি সেখানে কী করেছেন তবে কেবল সাম্প্রতিক পোস্টটি তৈরি করার তারিখটি ফিরে আসে, সেই সাম্প্রতিক পোস্টের পুরো সারিটি নয়।
রব ফরেস্ট

1
টুইটগুলি দেখুন আপনি লেখক কর্তৃক সাব-কোয়েরিতে সর্বাধিক সাম্প্রতিক পোস্টের তারিখটি ফিরিয়ে দেন এবং তারপরে wp_postsপুরো সারিটি পেতে আপনার উভয় কলামে ফিরে আসুন ।
Taryn

7
@ রবফোরেস্ট একের জন্য, যখন আপনি GROUP BYকেবল একটি কলামে প্রয়োগ করেন , অন্য কলামগুলির মানগুলি ধারাবাহিকভাবে সঠিক হবে এমন কোনও গ্যারান্টি নেই। দুর্ভাগ্যক্রমে, মাইএসকিউএল এই ধরণের নির্বাচন / গ্রুপিংকে অন্যান্য পণ্যগুলিতে না ঘটতে দেয়। দ্বিতীয়ত, ORDER BYএসকিউএল সার্ভার সহ অন্যান্য ডাটাবেস পণ্যগুলিতে মাইএসকিউএল-তে অনুমোদিত থাকার সময় একটি সাবকিউরিতে একটি ব্যবহারের বাক্য গঠনটি অনুমোদিত নয়। আপনার এমন একটি সমাধান ব্যবহার করা উচিত যা প্রতিবার কার্যকর করা হলে যথাযথ ফলাফলটি ফিরিয়ে দেয়।
Taryn

2
স্কেলিংয়ের জন্য, যৌগটি INDEX(post_author, post_date)গুরুত্বপূর্ণ।
রিক জেমস

1
@ জেটিকটন True৩ সত্য, তবে আপনি post_idযদি নিজের অভ্যন্তরীণ কোয়েরিটি রাখেন তবে প্রযুক্তিগতভাবে আপনি এটির দ্বারাও দলবদ্ধ করা উচিত, যা সম্ভবত আপনার ফলাফলগুলিকে ঝাঁকিয়ে দেবে।
তারিন

20

আপনার সমাধানটি গ্রুপের মাধ্যমে সম্প্রসারণের একটি বিস্তৃতি ব্যবহার করে যা কিছু ক্ষেত্র দ্বারা গ্রুপ করার অনুমতি দেয় (এই ক্ষেত্রে কেবলমাত্র post_author):

GROUP BY wp_posts.post_author

এবং অনাগ্রেগ্রেটেড কলামগুলি নির্বাচন করুন:

SELECT wp_posts.*

যেগুলি দফা দ্বারা গোষ্ঠীতে তালিকাভুক্ত নয়, বা এটি সামগ্রিক ফাংশনে (এমআইএন, ম্যাক্স, COUNT, ইত্যাদি) ব্যবহৃত হয় না।

অনুচ্ছেদে GROUP এ সম্প্রসারণের সঠিক ব্যবহার

এটি কার্যকর যখন অ-সংগৃহীত কলামগুলির সমস্ত মান প্রতিটি সারির জন্য সমান হয়।

উদাহরণস্বরূপ, ধরুন আপনার একটি টেবিল রয়েছে GardensFlowers( nameবাগানের, flowerযা বাগানে বেড়ে ওঠে):

INSERT INTO GardensFlowers VALUES
('Central Park',       'Magnolia'),
('Hyde Park',          'Tulip'),
('Gardens By The Bay', 'Peony'),
('Gardens By The Bay', 'Cherry Blossom');

এবং আপনি বাগানে যে সমস্ত ফুল গজায় সেগুলি বের করতে চান, যেখানে একাধিক ফুল জন্মায়। তারপরে আপনাকে একটি সাবকিউরি ব্যবহার করতে হবে, উদাহরণস্বরূপ আপনি এটি ব্যবহার করতে পারেন:

SELECT GardensFlowers.*
FROM   GardensFlowers
WHERE  name IN (SELECT   name
                FROM     GardensFlowers
                GROUP BY name
                HAVING   COUNT(DISTINCT flower)>1);

পরিবর্তে গার্ডারের একমাত্র ফুল যা আপনার সমস্ত ফুল থেকে বের করে নেওয়া দরকার, আপনি কেবল এই অবস্থায় থাকা অবস্থায় পরিবর্তন করতে পারবেন, তবে মাই এসকিএল HAVING COUNT(DISTINCT flower)=1আপনাকে এটি ব্যবহার করতে দেয়:

SELECT   GardensFlowers.*
FROM     GardensFlowers
GROUP BY name
HAVING   COUNT(DISTINCT flower)=1;

কোনও সাবকিউরি নয়, স্ট্যান্ডার্ড এসকিউএল নয়, তবে সহজ।

বিভাগের দ্বারা GROUP এ সম্প্রসারণের ভুল ব্যবহার

তবে আপনি যদি প্রতিটি সারির জন্য সমান নয় এমন অ-সমষ্টিযুক্ত কলামগুলি নির্বাচন করেন তবে কী হবে? মাইএসকিউএল column কলামটির জন্য কোন মানটি পছন্দ করে?

দেখে মনে হচ্ছে যে মাইএসকিউএল সর্বদা এর মুখোমুখি হওয়া প্রথম মানটি চয়ন করে ।

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

এই ধারণাটি দেওয়া যে মাইএসকিউএল সর্বদা এটির প্রথম সারিটি বেছে নেয়, আপনি গ্রুপের মাধ্যমে সঠিকভাবে সারিগুলি বাছাই করছেন। তবে দুর্ভাগ্যক্রমে, আপনি যদি ডকুমেন্টেশনটি মনোযোগ সহকারে পড়েন তবে আপনি লক্ষ্য করবেন যে এই অনুমানটি সত্য নয়।

সর্বদা এক নয় এমন অ-সংগৃহীত কলামগুলি নির্বাচন করার সময়, মাইএসকিউএল কোনও মান চয়ন করতে নিখরচায় থাকে, সুতরাং ফলস্বরূপ যে মানটি এটি প্রকৃতপক্ষে দেখায় তা অনির্দিষ্ট

আমি দেখতে পাচ্ছি যে অ-একত্রিত কলামের প্রথম মানটি পেতে এই কৌশলটি প্রচুর পরিমাণে ব্যবহৃত হয় এবং এটি সাধারণত / প্রায়শই সবসময় কাজ করে, আমি এটি কখনও কখনও পাশাপাশি ব্যবহার করি (আমার নিজের ঝুঁকিতে)। তবে এটি নথিভুক্ত না হওয়ায় আপনি এই আচরণের উপর নির্ভর করতে পারবেন না।

এই লিঙ্কটি (ধন্যবাদ ইপারকিউব!) গ্রুপ দ্বারা কৌশলটিকে অপ্টিমাইজ করা হয়েছে এমন পরিস্থিতি দেখায় যেখানে একই ক্যোয়ারী মাইএসকিএল এবং মারিয়াডিবি-র মধ্যে পৃথক ফলাফল দেয়, সম্ভবত কোনও ভিন্ন অপটিমাইজেশন ইঞ্জিনের কারণে।

সুতরাং, এই কৌশলটি যদি কাজ করে তবে এটি ভাগ্যের বিষয়।

অন্যান্য প্রশ্নে গৃহীত উত্তর আমার কাছে ভুল দেখায়:

HAVING wp_posts.post_date = MAX(wp_posts.post_date)

wp_posts.post_dateএটি একটি অ-সংগৃহীত কলাম এবং এটির মান আনুষ্ঠানিকভাবে নির্ধারিত হবে, তবে এটি সম্ভবত প্রথম post_dateমুখোমুখি হবে। তবে যেহেতু GROUP BY কৌশলটি একটি আনর্ডার্ডেড টেবিলের সাথে প্রয়োগ করা হয়েছে, এটি নিশ্চিত নয় যে কোনটি প্রথম post_dateসম্মুখীন হয়েছিল।

এটি সম্ভবত একক লেখকের একমাত্র পোস্ট এমন পোস্টগুলি ফিরিয়ে দেবে, তবে এটি সর্বদা নিশ্চিত নয়।

একটি সম্ভাব্য সমাধান

আমি মনে করি এটি একটি সম্ভাব্য সমাধান হতে পারে:

SELECT wp_posts.*
FROM   wp_posts
WHERE  id IN (
  SELECT max(id)
  FROM wp_posts
  WHERE (post_author, post_date) = (
    SELECT   post_author, max(post_date)
    FROM     wp_posts
    WHERE    wp_posts.post_status='publish'
             AND wp_posts.post_type='post'
    GROUP BY post_author
  ) AND wp_posts.post_status='publish'
    AND wp_posts.post_type='post'
  GROUP BY post_author
)

অভ্যন্তরীণ কোয়েরিতে আমি প্রতিটি লেখকের সর্বাধিক পোস্টের তারিখটি ফিরিয়ে দিচ্ছি। তারপরে আমি এই বিষয়টি বিবেচনা করছি যে একই লেখক তাত্ত্বিকভাবে একই সাথে দুটি পোস্ট থাকতে পারে, তাই আমি কেবল সর্বোচ্চ আইডি পাচ্ছি। এবং তারপরে আমি সর্বাধিক আইডি থাকা সমস্ত সারিটি ফিরিয়ে দিচ্ছি। এটি আইএন ক্লজের পরিবর্তে যোগ দিয়ে দ্রুত তৈরি করা যেতে পারে।

(যদি আপনি নিশ্চিত হন যে IDএটি কেবল বৃদ্ধি পাচ্ছে, এবং এর ID1 > ID2অর্থ যদি এর অর্থ হয় post_date1 > post_date2, তবে ক্যোয়ারীটি আরও সহজতর করা যেতে পারে, তবে আমি নিশ্চিত নই যে এটি ঘটনাটি কিনা)।


যে extension to GROUP Byএকটি আকর্ষণীয় পঠিত, যে জন্য ধন্যবাদ।
রব ফরেস্ট

2
এটি যেখানে ব্যর্থ হয় তার একটি উদাহরণ: গ্রুপ দ্বারা কৌতুকটি অপ্টিমাইজ করা হয়েছে
ypercubeᵀᴹ

GROUP BY এর সাথে নির্বাচিত এক্সপ্রেশনগুলিতে অ গ্রেগ্রেটেড কলামগুলি আর মাইএসকিউএল 5.7: স্ট্যাকওভারফ্লো / প্রশ্ন / 34115174/… দিয়ে ডিফল্টরূপে কাজ করে না । কোন আইএমএইচও বেশি নিরাপদ এবং কিছু লোককে আরও দক্ষ প্রশ্ন লিখতে বাধ্য করে।
rink.attendant.6

এই উত্তর একটি subquery ব্যবহার করে না? অরিজিনাল পোস্টার এমন কোনও সমাধানের জন্য জিজ্ঞাসা করছে না যা সাবকিউরি ব্যবহার করে না?
টিভি-সি -15

1
@ টিভি-সি -15 সমস্যাটি সাবকিউরিটি রিসর্ট করার ক্ষেত্রে রয়েছে এবং আমি ব্যাখ্যা করছি যে সাবকিউরিটির রিসর্টিং কেন কাজ করবে না। এমনকি গৃহীত উত্তরটিও একটি সাবকিউরি ব্যবহার করে তবে কেন এটি অবলম্বন করা একটি খারাপ ধারণা তা ব্যাখ্যা করা শুরু করে ( একটি সাবকিউয়ের মাধ্যমে অর্ডার ব্যবহার করা এই সমস্যার সর্বোত্তম সমাধান নয় )
fthiella

9

আপনি যা পড়তে চলেছেন তা হ্যাকি, তাই বাড়িতে এটি চেষ্টা করবেন না!

এসকিউএলে সাধারণভাবে আপনার প্রশ্নের উত্তরটি হ'ল না , তবে GROUP BY( ব্লুফিট দ্বারা উল্লিখিত ) শিথিল মোডের কারণে , উত্তরটি মাইএসকিউএলে হ্যাঁ হয়।

মনে করুন, আপনার (পোস্ট_স্ট্যাটাস, পোস্ট_টাইপ, পোস্ট_অর্থারেটর, পোস্ট_ডেট) একটি বিটিআরই সূচক রয়েছে। সূচকটি হুডের নীচে কেমন দেখাচ্ছে?

(পোস্ট_স্ট্যাটাস = 'প্রকাশ', পোস্ট_প্রকার = 'পোস্ট', পোস্ট_অক্ষেত্র = 'ব্যবহারকারী এ', পোস্ট_ডেট = '2012-12-01') (পোস্ট_স্ট্যাটাস = 'প্রকাশ', পোস্ট_ টাইপ = 'পোস্ট', পোস্ট_অ্যাটরাইট = 'ব্যবহারকারী এ', পোস্ট_ডেট = '২০১২-১২-৩১') (পোস্ট_স্ট্যাটাস = 'প্রকাশ', পোস্ট_প্রকার = 'পোস্ট', পোস্ট_অ্যাটোরিক = 'ব্যবহারকারী বি', পোস্ট_ডেট = '2012-10-01') (পোস্ট_স্ট্যাটাস = 'প্রকাশ', পোস্ট_ টাইপ = ' পোস্ট ', post_author =' ব্যবহারকারীর বি ', পোস্ট_ডেট =' 2012-12-01 ')

এটি ডেটা those সমস্ত ক্ষেত্রের দ্বারা আরোহী ক্রম অনুসারে বাছাই করা হয়।

আপনি যখন GROUP BYডিফল্টরূপে কোনও কাজটি করে থাকেন তখন এটি গ্রুপিং ফিল্ডের মাধ্যমে ডেটা post_authorসাজায় ( আমাদের ক্ষেত্রে; পোস্ট_স্ট্যাটাস, পোস্ট_ টাইপটি WHEREক্লজ দ্বারা আবশ্যক ) এবং যদি কোনও মিলের সূচক থাকে, তবে এটি প্রতিটি প্রথম রেকর্ডের জন্য আরোহণের ক্রমে ডেটা নেয়। এটাই হল কোয়েরিটি নিম্নলিখিত (প্রতিটি ব্যবহারকারীর জন্য প্রথম পোস্ট) আনবে:

(পোস্ট_স্ট্যাটাস = 'প্রকাশ', পোস্ট_প্রেম = 'পোস্ট', পোস্ট_অক্ষেত্র = 'ব্যবহারকারী এ', পোস্ট_ডেট = '2012-12-01') (পোস্ট_স্ট্যাটাস = 'প্রকাশ', পোস্ট_ টাইপ = 'পোস্ট', পোস্ট_অ্যাটরাইট = 'ব্যবহারকারী বি', POST_DATE = '2012-10-01')

তবে GROUP BYমাইএসকিউএল আপনাকে আদেশটি স্পষ্টভাবে নির্দিষ্ট করতে দেয়। এবং আপনি যখন post_userক্রম উতরে যাওয়ার অনুরোধ করবেন তখন এটি আমাদের সূচীটি বিপরীত ক্রমে চলে যাবে, এখনও প্রতিটি গ্রুপের জন্য এটি প্রথম রেকর্ড গ্রহণ করবে যা আসলে শেষ।

এটাই

...
WHERE wp_posts.post_status='publish' AND wp_posts.post_type='post'
GROUP BY wp_posts.post_author DESC

আমাদের দেবে

(পোস্ট_স্ট্যাটাস = 'প্রকাশ', পোস্ট_প্রকার = 'পোস্ট', পোস্ট_অক্ষেত্র = 'ব্যবহারকারীর বি', পোস্ট_ডেট = '2012-12-01') (পোস্ট_স্ট্যাটাস = 'প্রকাশ', পোস্ট_প্রকার = 'পোস্ট', পোস্ট_অক্ষেত্র = 'ব্যবহারকারী এ', POST_DATE = '2012-12-31')

এখন, আপনি যখন পোস্ট_ডেটের মাধ্যমে গ্রুপিংয়ের ফলাফলগুলি অর্ডার করেন, তখন আপনি যে তথ্যটি চেয়েছিলেন তা পেয়ে যান।

SELECT wp_posts.*
FROM wp_posts
WHERE wp_posts.post_status='publish' AND wp_posts.post_type='post'
GROUP BY wp_posts.post_author DESC
ORDER BY wp_posts.post_date DESC;

এনবি :

আমি এই বিশেষ প্রশ্নের জন্য সুপারিশ করব তা নয়। এই ক্ষেত্রে, আমি @ ব্লুয়েফেটের পরামর্শ অনুসারে কিছুটা পরিবর্তিত সংস্করণ ব্যবহার করব । তবে এই কৌশলটি খুব কার্যকর হতে পারে। আমার উত্তরটি এখানে দেখুন: প্রতিটি গ্রুপে শেষ রেকর্ড পুনরুদ্ধার করা

সমস্যাগুলি : পদ্ধতির অসুবিধাগুলি হ'ল এটি

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

সুবিধাটি হ'ল হার্ড ক্ষেত্রে পারফরম্যান্স। এই ক্ষেত্রে, ক্যোয়ারির কার্য সম্পাদন @ ব্লুফিটের ক্যোয়ারির মতোই হওয়া উচিত, কারণ বাছাইয়ের সাথে জড়িত ডেটার পরিমাণের কারণে (সমস্ত ডেটা একটি অস্থায়ী টেবিলের মধ্যে লোড করা হয় এবং পরে বাছাই করা হয়; বিটিডব্লিউ, তার ক্যোয়ারিতেও (post_status, post_type, post_author, post_date)সূচি প্রয়োজন ) ।

আমি কি পরামর্শ দেব :

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

SELECT * 
FROM wp_posts
INNER JOIN
(
  SELECT max(post_date) post_date, post_author
  FROM wp_posts
  WHERE post_status='publish' AND post_type='post'
  GROUP BY post_author
  ORDER BY post_date DESC
  -- LIMIT GOES HERE
) p2 USING (post_author, post_date)
WHERE post_status='publish' AND post_type='post';

উপরে বর্ণিত পদ্ধতির ব্যবহার করে একই ক্যোয়ারী:

SELECT *
FROM (
  SELECT post_id
  FROM wp_posts
  WHERE post_status='publish' AND post_type='post'
  GROUP BY post_author DESC
  ORDER BY post_date DESC
  -- LIMIT GOES HERE
) as ids
JOIN wp_posts USING (post_id);

তাদের ফাঁসি পরিকল্পনা সংগীদের সবাইকে প্রশ্নের SQLFiddle


এটি একটি আকর্ষণীয় কৌশল আপনি সেখানে যেতে পেয়েছেন। দুটি জিনিস: আপনি বলেন যে বাড়িতে এটি চেষ্টা করবেন না, সম্ভাব্য সমস্যাগুলি কী কী? দ্বিতীয়ত, আপনি ব্লুফীটের উত্তরের কিছুটা পরিবর্তিত সংস্করণ উল্লেখ করেছেন, তা কী হবে?
রব ফরেস্ট

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

8

আর একবার চেষ্টা কর. কেবলমাত্র প্রতিটি লেখকের কাছ থেকে সর্বশেষ পোস্টের তারিখগুলির তালিকা পান । এটাই

SELECT wp_posts.* FROM wp_posts WHERE wp_posts.post_status='publish'
AND wp_posts.post_type='post' AND wp_posts.post_date IN(SELECT MAX(wp_posts.post_date) FROM wp_posts GROUP BY wp_posts.post_author) 

@ রব ফরেস্ট, আমার সমাধানটি পরীক্ষা করুন। এটি আপনার প্রশ্নের সমাধান করে, আশা করি!
sanchitkhanna26

1
আমি দুঃখিত, আমি মনে করি না যে এটি কার্যকর হবে। উদাহরণস্বরূপ, যদি লেখক 1 এবং লেখক 2 উভয়ই 01/02/13 তে কিছু প্রকাশ করেন এবং তারপরে লেখক 2 08/02/13 তে নতুন কিছু পোস্ট করেন, সমস্ত 3 টি পোস্ট ফিরে আসবে। হ্যাঁ তারিখের সময় ক্ষেত্রটিতে সময় অন্তর্ভুক্ত থাকে তাই পরিস্থিতি কম সম্ভাবনা থাকে তবে কোনওভাবেই এটি যথেষ্ট পরিমাণে ডেটাসেটের গ্যারান্টিযুক্ত নয়।
রব ফরেস্ট

ব্যবহারের জন্য +1 post_date IN (select max(...) ...)। উপ-নির্বাচনের মাধ্যমে একটি দল করার চেয়ে এটি আরও দক্ষ, দেখুন dev.mysql.com/doc/refman/5.6/en/subquery-optimization.html
Seaux

কেবল স্পষ্ট করার জন্য, এটি পোস্টটি প্রামাণিকভাবে তালিকাবদ্ধ থাকলে কেবলমাত্র আরও অনুকূল।
সিউক্স

1
IN ( SELECT ... )সমতুল্য জোয়ানের তুলনায় অনেক কম দক্ষ।
রিক জেমস

3

না। গ্রুপিংয়ের আগে রেকর্ডগুলি অর্ডার করা কোনও অর্থবোধ করে না, যেহেতু গোষ্ঠীকরণ ফলাফল সেটটিকে পরিবর্তন করতে চলেছে। Subquery উপায় পছন্দের উপায়। যদি এটি খুব ধীর হয়ে চলেছে তবে আপনাকে আপনার টেবিলের নকশাটি পরিবর্তন করতে হবে, উদাহরণস্বরূপ, প্রতিটি লেখকের জন্য পৃথক টেবিলের সর্বশেষ পোস্টের আইডি সঞ্চয় করে, বা প্রতিটি লেখকের জন্য নির্দেশিত একটি বুলিয়ান কলাম প্রবর্তন করুন যা তাঁর পোস্টের শেষটি কোনটি? এক.


ড্যানিশ, ব্লুফীটের এই মন্তব্যে আপনি কীভাবে প্রতিক্রিয়া জানাতে পারেন যে এই ধরণের কোয়েরিটি সঠিক এসকিউএল সিনট্যাক্স নয় এবং তাই ডাটাবেস প্ল্যাটফর্মের মধ্যে বহনযোগ্য নয়? এগুলি নিয়েও উদ্বেগ রয়েছে যে এটি প্রতিবারই সঠিক ফলাফল আনতে পারে এমন কোনও গ্যারান্টি নেই।
রব ফরেস্ট

2

সর্বাধিক ফাংশন এবং গ্রুপ ফাংশনটি ব্যবহার করুন

    select max(taskhistory.id) as id from taskhistory
            group by taskhistory.taskid
            order by taskhistory.datum desc

3
সর্বাধিক আইডির সাথে সর্বাধিক পোস্ট করা না হলে কী হবে? এর একটি উদাহরণ হতে পারে যে লেখক দীর্ঘ সময় ধরে তার পোস্টটি পোস্ট করার আগে খসড়ায় রেখেছিলেন।
রব ফরেস্ট

0

কেবল পুনরুদ্ধার করার জন্য, মানক সমাধানটি একটি নিরবিচ্ছিন্ন সাবকোয়ারি ব্যবহার করে এবং এর মতো দেখায়:

SELECT x.*
  FROM my_table x
  JOIN (SELECT grouping_criteria,MAX(ranking_criterion) max_n FROM my_table GROUP BY grouping_criteria) y
    ON y.grouping_criteria = x.grouping_criteria
   AND y.max_n = x.ranking_criterion;

আপনি যদি মাইএসকিউএলের একটি প্রাচীন সংস্করণ বা মোটামুটি ছোট ডেটা সেট ব্যবহার করছেন তবে আপনি নিম্নলিখিত পদ্ধতিটি ব্যবহার করতে পারেন:

SELECT x.*
  FROM my_table x
  LEFT
  JOIN my_table y
    ON y.joining_criteria = x.joining_criteria
   AND y.ranking_criteria < x.ranking_criteria
 WHERE y.some_non_null_column IS NULL;  

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

এটি কোনও সংস্করণে (ধীরে ধীরে) কাজ করবে। পুরানো সংস্করণ সাবকোয়ারি ব্যবহার করতে পারে না।
স্ট্রবেরি

হাঁ, পদ্ধতি # 2 (সংস্করণ আমি চেষ্টা করেছি থেকে এখানে ) হবে বৃহৎ ডেটাসেটের (সারি লক্ষ লক্ষ) কাজ করে না, একটি ছোঁড়ার হারিয়ে সংযোগ ত্রুটি। পদ্ধতি # 1 একটি ক্যোয়ারি চালাতে seconds 15 সেকেন্ড সময় নেয়। আমি প্রাথমিকভাবে নেস্টেড ক্যোয়ারীগুলি ব্যবহার করা এড়াতে চেয়েছিলাম, তবে এটি আমাকে পুনর্বিবেচনা করেছে। ধন্যবাদ!
এক্সেল

পছন্দ করুন সাড়ে ৩ বছরে তেমন কোনও পরিবর্তন হয়নি। ধরে নেওয়া যে কোনও ক্যোয়ারী নিজেই দক্ষ, তারপরে কোয়েরিটি কার্যকর করতে যে সময় লাগে তা মূলত ডেটাसेटের আকার, সূচীর বিন্যাস এবং উপলব্ধ হার্ডওয়্যারের উপর নির্ভর করে।
স্ট্রবেরি

-1

** সাব ডাবলগুলি বড় ডেটাসেট ব্যবহার করার সময় পারফরম্যান্সে খারাপ প্রভাব ফেলতে পারে **

মূল ক্যোয়ারী

SELECT wp_posts.*
FROM   wp_posts
WHERE  wp_posts.post_status = 'publish'
       AND wp_posts.post_type = 'post'
GROUP  BY wp_posts.post_author
ORDER  BY wp_posts.post_date DESC; 

পরিবর্তিত ক্যোয়ারী

SELECT p.post_status,
       p.post_type,
       Max(p.post_date),
       p.post_author
FROM   wp_posts P
WHERE  p.post_status = "publish"
       AND p.post_type = "post"
GROUP  BY p.post_author
ORDER  BY p.post_date; 

কারনে আমি ব্যবহার করছি maxমধ্যে select clause==> max(p.post_date)এটি দ্বারা গ্রুপ পর সাব নির্বাচন জিজ্ঞাস্য এবং সর্বোচ্চ কলাম দ্বারা এড়ানোর করা সম্ভব।


1
এটি প্রকৃতপক্ষে লেখক হিসাবে সর্বাধিক সাম্প্রতিক পোস্ট_ডেটটি ফিরিয়ে দেয় তবে যে গ্যারান্টি নেই যে ফিরিয়ে দেওয়া হয়েছে সেই তথ্যটি সাম্প্রতিক পোস্ট_ডেটের সাথে পোস্টের সাথে সম্পর্কিত।
রব ফরেস্ট

@ রবফোরেস্ট -> কেন বুঝতে পারছি না? আপনার উত্তরটি বিস্তৃত করা এবং দাবীগুলি ছড়িয়ে দেওয়া ভাল ধারণা। আমি যতদূর বুঝি ডেটা সম্পর্কিত হওয়ার নিশ্চয়তা রয়েছে কারণ আমি যেখানে সম্পর্কিত ডেটা ফিল্টার করার জন্য ক্লজ ব্যবহার করি।
লোকক্যাপলান

1
কিছুটা হলেও, আপনি সম্পূর্ণরূপে সঠিক, আপনি যে 4 টি ক্ষেত্র নির্বাচন করছেন তার প্রত্যেকটি সেই সর্বোচ্চ পোস্ট_ডেটের সাথে সম্পর্কিত হবে, তবে এটি যে প্রশ্নটি জিজ্ঞাসা করেছিল তার উত্তর দেয় না। উদাহরণস্বরূপ, আপনি যদি পোস্ট_আইড, বা পোস্টের বিষয়বস্তুগুলি যুক্ত করেন তবে সেই কলামগুলি সর্বোচ্চ তারিখের মতো একই রেকর্ড থেকে আসার আশ্বাস দেওয়া হবে না। পোস্টের বিশদ বিশদটি ফেরত পেতে উপরের উপরে আপনার জিজ্ঞাসাটি পেতে আপনাকে দ্বিতীয় কোয়েরি চালাতে হবে। যদি প্রশ্নটি সর্বাধিক সাম্প্রতিক পোস্টের তারিখ সন্ধানের বিষয়ে ছিল, তবে হ্যাঁ আপনি উত্তরটি ঠিক রাখবেন।
রব ফরেস্ট

@ গুয়্যাকাপ্লান, সাবকিউরিগুলি ধীর নয়। ডেটা সেটের আকারের কোনও ব্যাপার নেই। এটি আপনি কীভাবে ব্যবহার করেন তার উপর নির্ভর করে। পারকোনা.com
blog/

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

-4

প্রথমত, * ব্যবহারে * ব্যবহার করবেন না, তাদের কর্মক্ষমতা প্রভাবিত করে এবং গোষ্ঠীটির ব্যবহার দ্বারা বা আদেশ দিয়ে বাধা দেয়। এই কোয়েরিটি চেষ্টা করে দেখুন:

SELECT wp_posts.post_author, wp_posts.post_date as pdate FROM wp_posts
WHERE wp_posts.post_status='publish'
AND wp_posts.post_type='post'
GROUP BY wp_posts.post_author           
ORDER BY pdate DESC

আপনি যখন কেবলমাত্র ওরফে অর্ডার দ্বারা সারণী নির্দিষ্ট না করে, তারা নির্বাচনের ফলাফলের আদেশ দেবে।


নির্বাচন করুন * এর অগ্রাহ্য করুন, তারা উদাহরণস্বরূপ ব্রিভিটির জন্য। আপনার উত্তরটি আমি প্রথম উদাহরণ হিসাবে দেওয়া ঠিক একই।
রব ফরেস্ট

কোন সারিটি ফিরে আসে বা ফলাফলগুলি বাছাই করে তার কোনও নাম নেই।
রব ফরেস্ট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.