समूह द्वारा पहले MySQL आदेश


243

यहाँ पर ऐसे ही बहुत सारे प्रश्न पाए जाते हैं, लेकिन मुझे नहीं लगता कि कोई भी प्रश्न पर्याप्त रूप से उत्तर देता है।

मैं वर्तमान सबसे लोकप्रिय प्रश्न से जारी रखूंगा और उनके उदाहरण का उपयोग करूंगा यदि यह ठीक है।

इस उदाहरण में कार्य डेटाबेस में प्रत्येक लेखक के लिए नवीनतम पोस्ट प्राप्त करना है।

उदाहरण क्वेरी अनुपयोगी परिणाम उत्पन्न करती है क्योंकि यह हमेशा नवीनतम पोस्ट नहीं होती है।

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

दुर्भाग्य से यह उत्तर स्पष्ट और सरल गलत है और कई मामलों में मूल क्वेरी की तुलना में कम स्थिर परिणाम पैदा करता है।

मेरा सबसे अच्छा समाधान फार्म की एक उपवर्ग का उपयोग करना है

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
सर रूफो

@SirRufo आप सही हैं, मैंने आपके लिए एक संपादन में जोड़ा है।
रोब फॉरेस्ट

There are plenty of similar questions to be found on here but I don't think that any answer the question adequately.यही तो इनाम हैं।
१०:१३ पर कक्षा

@LightnessRacesinOrbit, यदि वर्तमान प्रश्न में पहले से ही एक स्वीकृत जवाब है कि मेरी राय में गलत है, तो आप क्या करने का सुझाव देंगे?
रोब फॉरेस्ट

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

फिर चूंकि आप उस तालिका में वापस शामिल हो रहे हैं, दोनों मानों पर आप उस पोस्ट का पूरा विवरण वापस कर देंगे।

SQL फिडेल को डेमो के साथ देखें ।

इस डेटा को सटीक रूप से वापस करने के लिए एक उप-वर्ग का उपयोग करने के बारे में मेरी टिप्पणियों पर विस्तार करने के लिए।

MySQL GROUP BYआपको SELECTसूची में शामिल हर कॉलम के लिए मजबूर नहीं करता है । परिणामस्वरूप, यदि आप केवल GROUP BYएक स्तंभ पर कुल 10 कॉलम लौटाते हैं, तो इस बात की कोई गारंटी नहीं है कि अन्य स्तंभ मान जो post_authorउस से संबंधित हैं , वापस आ गया है। यदि स्तंभ GROUP BYMySQL में नहीं है, तो चुनता है कि किस मूल्य को वापस किया जाना चाहिए।

समुच्चय के साथ समुच्चय का उपयोग करना यह गारंटी देगा कि सही लेखक और पोस्ट को हर बार लौटाया जाता है।

एक साइड नोट के रूप में, जबकि MySQL आपको एक सब-वे ORDER BYमें उपयोग करने की अनुमति देता है और आपको इस सूची में SQL सर्वर सहित अन्य डेटाबेस में इस व्यवहार की अनुमति GROUP BYनहीं है, प्रत्येक कॉलम को लागू करने की अनुमति देता है SELECT


4
मैं देखता हूं कि आपने वहां क्या किया है, लेकिन बस उस तारीख को वापस करता है जो सबसे हालिया पोस्ट बना था, उस सबसे हालिया पोस्ट के लिए पूरी पंक्ति नहीं थी।
रोब फॉरेस्ट

1
@RobForrest जो जुड़ता है। आप लेखक द्वारा सबक्वेरी में सबसे हालिया पोस्ट डेट लौटाते हैं और फिर wp_postsपूरी पंक्ति प्राप्त करने के लिए अपने दोनों कॉलम में वापस शामिल होते हैं।
टैरिन

7
@RobForrest एक के लिए, जब आप GROUP BYकेवल एक कॉलम पर लागू होते हैं , तो इस बात की कोई गारंटी नहीं है कि दूसरे कॉलम में मान लगातार सही होंगे। दुर्भाग्यवश, MySQL इस प्रकार के SELECT / GROUPing को अन्य उत्पादों के न होने की अनुमति देता है। दो, ORDER BYMySQL में अनुमति के समय एक सबक्वेरी में उपयोग किए जाने वाले सिंटैक्स को SQL सर्वर सहित अन्य डेटाबेस उत्पादों में अनुमति नहीं है। आपको एक समाधान का उपयोग करना चाहिए जो हर बार निष्पादित होने पर उचित परिणाम लौटाएगा।
तरण

2
स्केलिंग के लिए, यौगिक INDEX(post_author, post_date)महत्वपूर्ण है।
रिक जेम्स

1
@ jtcotton63 सच है, लेकिन अगर आप post_idअपनी आंतरिक क्वेरी में डालते हैं , तो तकनीकी रूप से आपको इसके साथ ही समूह बनाना चाहिए, जो आपके परिणामों को सबसे अधिक तिरछा करेगा।
टैरिन

20

आपका समाधान ग्रुप बाय क्लाज के लिए एक एक्सटेंशन का उपयोग करता है जो कुछ क्षेत्रों द्वारा समूह को अनुमति देता है (इस मामले में, बस post_author):

GROUP BY wp_posts.post_author

और गैर-पृथक कॉलम चुनें:

SELECT wp_posts.*

जो समूह में खंड द्वारा सूचीबद्ध नहीं हैं, या जिनका उपयोग कुल कार्य (MIN, MAX, COUNT, आदि) में नहीं किया गया है।

समूह द्वारा खंड के विस्तार का सही उपयोग

यह तब उपयोगी है जब गैर-एकत्रित कॉलम के सभी मान हर पंक्ति के लिए समान हों।

उदाहरण के लिए, मान लीजिए कि आपके पास एक टेबल है 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 की स्थिति को बदल सकते हैं HAVING COUNT(DISTINCT flower)=1, लेकिन MySql भी आपको इसका उपयोग करने की अनुमति देता है:

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

कोई उपवर्ग नहीं, मानक एसक्यूएल नहीं, लेकिन सरल।

ग्रुप बाय क्लाज द्वारा एक्सटेंशन का गलत उपयोग

लेकिन क्या होगा यदि आप गैर-एकत्रित स्तंभों का चयन करते हैं जो हर पंक्ति के लिए समान नहीं हैं? वह मान क्या है जो MySql उस कॉलम के लिए चुनता है?

ऐसा लगता है कि MySql हमेशा अपने द्वारा सामना किए जाने वाले FIRST मूल्य को चुनता है ।

यह सुनिश्चित करने के लिए कि इसका पहला मूल्य आपके द्वारा वांछित मूल्य है, आपको GROUP BYएक ऑर्डर किए गए क्वेरी को लागू करने की आवश्यकता है, इसलिए उप-वर्ग का उपयोग करने की आवश्यकता है। आप इसे अन्यथा नहीं कर सकते।

इस धारणा को देखते हुए कि MySql हमेशा पहली पंक्ति को चुनता है जिससे उसका सामना होता है, आप हर बार पंक्तियों को GROUP BY से पहले छांट रहे हैं। लेकिन दुर्भाग्य से, यदि आप प्रलेखन को ध्यान से पढ़ते हैं, तो आप देखेंगे कि यह धारणा सही नहीं है।

गैर-एकत्रित कॉलम का चयन करते समय, जो हमेशा समान नहीं होते हैं, MySql किसी भी मूल्य का चयन करने के लिए स्वतंत्र है, इसलिए परिणामी मूल्य जो वास्तव में दिखाता है वह अनिश्चित है

मैं देखता हूं कि गैर-एकत्रित कॉलम का पहला मूल्य प्राप्त करने के लिए इस ट्रिक का बहुत उपयोग किया जाता है, और यह आमतौर पर / लगभग हमेशा काम करता है, मैं इसे कभी-कभी (अपने जोखिम पर) उपयोग करता हूं। लेकिन चूंकि यह प्रलेखित नहीं है, इसलिए आप इस व्यवहार पर भरोसा नहीं कर सकते।

यह लिंक (धन्यवाद ypercube!) ग्रुप बाय ट्रिक को ऑप्टिमाइज़ किया गया है एक ऐसी स्थिति को दिखाता है जिसमें एक ही क्वेरी MySql और MariaDB के बीच अलग-अलग परिणाम देता है, शायद एक अलग अनुकूलन इंजन के कारण।

तो, अगर यह चाल काम करती है, तो यह सिर्फ भाग्य की बात है।

अन्य सवाल पर स्वीकार किए जाते हैं जवाब मेरे लिए गलत लग रहा है:

HAVING wp_posts.post_date = MAX(wp_posts.post_date)

wp_posts.post_dateएक गैर-एकत्रित कॉलम है, और इसका मूल्य आधिकारिक तौर पर अनिर्धारित होगा, लेकिन यह संभवतः पहले post_dateसामना किया जाएगा। लेकिन चूंकि ग्रुप बाय ट्रिक को अनऑर्डर्ड टेबल पर लागू किया जाता है, इसलिए यह सुनिश्चित नहीं होता है कि पहले 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
)

भीतर की क्वेरी पर मैं हर लेखक के लिए अधिकतम पोस्ट डेट लौटा रहा हूं। मैं तब इस तथ्य पर विचार कर रहा हूं कि एक ही लेखक के पास एक ही समय में दो पद हो सकते हैं, इसलिए मुझे केवल अधिकतम आईडी मिल रही है। और फिर मैं उन सभी पंक्तियों को वापस कर रहा हूं जिनमें उन अधिकतम आईडी हैं। इसे IN क्लॉज के बजाय जॉइन का इस्तेमाल करके तेजी से बनाया जा सकता है।

(यदि आपको यकीन है कि IDयह केवल बढ़ रहा है, और यदि ID1 > ID2इसका मतलब यह भी है post_date1 > post_date2, तो क्वेरी को और अधिक सरल बनाया जा सकता है, लेकिन मुझे यकीन नहीं है कि यह मामला है)।


यह extension to GROUP Byएक दिलचस्प रीड है, इसके लिए धन्यवाद।
रॉब फॉरेस्ट

2
एक उदाहरण जहां यह विफल रहता है: ग्रुप बाय ट्रिक को अनुकूलित किया गया है
ypercube '

समूह के साथ कुछ चुनिंदा अभिव्यक्तियों में अस्वाभाविक कॉलम MySQL 5.7 के साथ डिफ़ॉल्ट रूप से काम नहीं करता है: stackoverflow.com/questions/34115174/… । कौन सा IMHO ज्यादा सुरक्षित है और कुछ लोगों को अधिक कुशल प्रश्न लिखने के लिए मजबूर करता है।
रिंक.टेंटेंड ।6

क्या यह उत्तर उपकुंजी का उपयोग नहीं करता है? क्या मूल पोस्टर एक समाधान के लिए नहीं कह रहा है जो एक उपकुंजी का उपयोग नहीं करता है?
टीवी-सी -15

1
@ टीवी-सी -15 की समस्या उपकुंजी के सहारा के साथ है, और मैं यह बता रहा हूं कि उपकुंजी का सहारा लेने से काम क्यों नहीं चलेगा। यहां तक ​​कि स्वीकृत उत्तर एक उपशम का उपयोग करता है, लेकिन यह व्याख्या करना शुरू कर देता है कि क्यों सहारा लेना एक बुरा विचार है ( एक आदेश में एक आदेश का उपयोग करना ) इस समस्या का सबसे अच्छा समाधान नहीं है
फेटीला

9

आप जो पढने जा रहे हैं, वह हैक करने योग्य है, इसलिए घर पर इसका प्रयास न करें!

SQL में सामान्य रूप से आपके प्रश्न का उत्तर NO है , लेकिन GROUP BY( @bluefeet द्वारा उल्लिखित ) के रिलैक्स मोड के कारण , इसका उत्तर MySQL में YES है।

मान लीजिए, आपके पास BTREE इंडेक्स (पोस्ट_स्टैटस, पोस्ट_टाइप, पोस्ट_ओथोर, पोस्ट_टेट) है। सूचकांक हुड के नीचे कैसे दिखता है?

(post_status = 'publish', post_type = 'post', post_author = 'user A', post_date = '2012-12-01') (post_status = 'publish', post_type = "post ', post_author =' user A ',) post_date = '2012-12-31') (post_status = 'publish', post_type = 'post', post_author = 'user B', post_date = '2012-10-01') (post_status = 'publish', post_type = ' post ', post_author =' user B ', post_date =' 2012-12-01 ')

डेटा को आरोही क्रम में उन सभी क्षेत्रों द्वारा सॉर्ट किया जाता है।

जब आप GROUP BYडिफ़ॉल्ट रूप से ऐसा कर रहे होते हैं तो यह समूहीकरण फ़ील्ड द्वारा डेटा सॉर्ट करता है ( post_authorहमारे मामले में; पोस्ट_स्टैटस, पोस्ट_टाइप को WHEREक्लॉज़ द्वारा आवश्यक होता है ) और यदि कोई मेलिंग इंडेक्स है, तो यह आरोही क्रम में प्रत्येक पहले रिकॉर्ड के लिए डेटा लेता है। यह प्रश्न निम्नलिखित होगा (प्रत्येक उपयोगकर्ता के लिए पहला पद):

(post_status = 'publish', post_type = 'post', post_author = 'user A', post_date = '2012-12-01') (post_status = 'publish', post_type = "post ', post_author =' user B ',) POST_DATE = '2012-10-01')

लेकिन GROUP BYMySQL में आप आदेश को स्पष्ट रूप से निर्दिष्ट करने की अनुमति देते हैं। और जब आप post_userअवरोही क्रम में अनुरोध करते हैं , तो यह विपरीत क्रम में हमारे सूचकांक के माध्यम से चलेगा, फिर भी प्रत्येक समूह के लिए पहला रिकॉर्ड लेगा जो वास्तव में अंतिम है।

अर्थात्

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

हमें दे देंगे

(post_status = 'publish', post_type = 'post', post_author = 'user B', post_date = '2012-12-01') (post_status = 'publish', post_type = "post ', post_author =' user A ',) POST_DATE = '2012-12-31')

अब, जब आप post_date द्वारा समूहीकरण के परिणाम का आदेश देते हैं, तो आपको वह डेटा मिलता है जो आप चाहते थे।

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;

NB :

यह वह नहीं है जो मैं इस विशेष प्रश्न के लिए सुझाऊंगा। इस मामले में, मैं @bluefeet के थोड़े संशोधित संस्करण का उपयोग करूंगा । लेकिन यह तकनीक बहुत उपयोगी हो सकती है। यहाँ मेरे उत्तर पर एक नज़र डालें: प्रत्येक समूह में पिछले रिकॉर्ड को पुनः प्राप्त करें

नुकसान : दृष्टिकोण का नुकसान यह है कि

  • क्वेरी का परिणाम सूचकांक पर निर्भर करता है, जो कि एसक्यूएल की भावना के खिलाफ है (इंडेक्स केवल प्रश्नों को गति देना चाहिए);
  • इंडेक्स क्वेरी पर इसके प्रभाव के बारे में कुछ भी नहीं जानता है (आप या भविष्य में कोई अन्य व्यक्ति इंडेक्स को बहुत अधिक संसाधन-उपभोग कर सकता है और इसे किसी भी तरह बदल सकता है, क्वेरी के परिणाम को तोड़ सकता है, न केवल इसके प्रदर्शन को)
  • यदि आपको समझ में नहीं आता है कि क्वेरी कैसे काम करती है, तो शायद आप एक महीने में स्पष्टीकरण भूल जाएंगे और क्वेरी आपको और आपके सहयोगियों को भ्रमित कर देगी।

लाभ कठिन मामलों में प्रदर्शन है। इस स्थिति में, क्वेरी का प्रदर्शन @ ब्लूफीट क्वेरी में समान होना चाहिए, क्योंकि डेटा की मात्रा छँटाई में शामिल है (सभी डेटा को एक अस्थायी तालिका में लोड किया जाता है और फिर सॉर्ट किया जाता है; btw, उसकी क्वेरी को (post_status, post_type, post_author, post_date)सूचकांक की भी आवश्यकता होती है ) ।

मैं क्या सुझाव दूंगा :

जैसा कि मैंने कहा, उन प्रश्नों के कारण MySQL का समय बर्बाद हो जाता है जो अस्थायी रूप से बड़ी मात्रा में डेटा को एक अस्थायी तालिका में क्रमबद्ध करता है। यदि आपको पेजिंग की आवश्यकता है (जो कि लिमिट शामिल है) तो अधिकांश डेटा को फेंक दिया जाता है। मैं क्या करूंगा सॉर्ट किए गए डेटा की मात्रा को कम से कम करना: यह सॉर्ट करना है और सबक्वेरी में न्यूनतम डेटा को सीमित करना और फिर पूरे टेबल पर वापस शामिल होना।

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 पर उनके निष्पादन योजनाओं के साथ उन सभी प्रश्नों ।


यह एक दिलचस्प तकनीक है जिससे आप वहां जा रहे हैं। दो बातें: आप कहते हैं कि घर पर यह कोशिश मत करो, संभावित नुकसान क्या हैं? दूसरी बात, आप ब्लूफेट के उत्तर के थोड़ा संशोधित संस्करण का उल्लेख करते हैं, वह क्या होगा?
रॉब फॉरेस्ट

इसके लिए धन्यवाद, किसी को समस्या पर हमला करते हुए देखने के लिए इसका दिलचस्प तरीका। जैसा कि मेरा डेटा सेट आपकी 18M + पंक्तियों के पास नहीं है, मुझे नहीं लगता कि प्रदर्शन स्थिरता के रूप में महत्वपूर्ण है, इसलिए मुझे लगता है कि आपके बाद के विकल्प संभवतः अधिक उपयुक्त हैं। मुझे उपनगर के अंदर की सीमा का विचार पसंद है।
रोब फॉरेस्ट

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
सीउक्स

यदि आप post_author अनुक्रमित हैं, तो केवल स्पष्ट करने के लिए, यह केवल अधिक इष्टतम है।
सीवक्स

1
IN ( SELECT ... )बराबर JOIN की तुलना में बहुत कम कुशल है।
रिक जेम्स

3

नहीं, इससे कोई मतलब नहीं है कि समूह बनाने से पहले रिकॉर्ड का आदेश दिया जाए, क्योंकि समूहन परिणाम सेट को म्यूट करने जा रहा है। उपशम मार्ग पसंदीदा तरीका है। यदि यह बहुत धीमी गति से चल रहा है, तो आपको अपनी तालिका के डिज़ाइन को बदलना होगा, उदाहरण के लिए प्रत्येक लेखक के लिए एक अलग तालिका में अंतिम पोस्ट की आईडी को संग्रहीत करके, या प्रत्येक लेखक के लिए एक बुलियन कॉलम का परिचय देता है कि उसका कौन सा पद अंतिम है एक।


डेनिश, आप ब्लूफेट की टिप्पणियों पर कैसे प्रतिक्रिया देंगे कि इस प्रकार का क्वेरी SQL सिंटैक्स सही नहीं है और इसलिए डेटाबेस प्लेटफार्मों पर पोर्टेबल नहीं है? यह भी चिंता है कि इस बात की कोई गारंटी नहीं है कि यह हर बार सही परिणाम देगा।
रोब फॉरेस्ट

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;

यदि आप MySQL के प्राचीन संस्करण का उपयोग कर रहे हैं, या एक काफी छोटा डेटा सेट है, तो आप निम्न विधि का उपयोग कर सकते हैं:

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;  

जब आप प्राचीन संस्करण कहते हैं, तो MySQL का कौन सा संस्करण चालू होगा? और क्षमा करें नहीं, मेरे उदाहरण में डेटासेट काफी बड़ा है।
रॉब फॉरेस्ट

यह किसी भी संस्करण पर (धीरे) काम करेगा। पुराने संस्करण उप-वर्ग का उपयोग नहीं कर सकते हैं।
स्ट्रॉबेरी

हां, विधि # 2 (मैंने जिस संस्करण की कोशिश की है, वह यहां से है ) एक बड़े डेटासेट (लाखों पंक्तियों) पर काम नहीं करेगा, एक खोया कनेक्शन त्रुटि फेंकता है । विधि # 1 किसी क्वेरी को निष्पादित करने के लिए ~ 15 सेकंड लेता है। मैं शुरू में नेस्टेड प्रश्नों का उपयोग करने से बचना चाहता था, लेकिन इससे मुझे पुनर्विचार करना पड़ा। धन्यवाद!
एक्सेल

@TheSexiestManinJamaica हाँ। 3.5 वर्षों में बहुत कुछ नहीं बदला है। एक क्वेरी मान लेना अपने आप में कुशल है, तो क्वेरी को निष्पादित करने में लगने वाला समय काफी हद तक डेटासेट के आकार, अनुक्रमित की व्यवस्था और उपलब्ध हार्डवेयर पर निर्भर करता है।
स्ट्रॉबेरी

-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
यह वास्तव में प्रति लेखक सबसे हाल का पोस्ट_डेट लौटाता है लेकिन इस बात की कोई गारंटी नहीं है कि लौटाए गए बाकी डेटा सबसे हाल के पोस्ट_डेट के साथ संबंधित हैं।
रॉब फॉरेस्ट

@RobForrest -> मुझे समझ में क्यों नहीं आता? यह एक अच्छा विचार है कि अपने उत्तर को विस्तृत करें और केवल दावों को बाहर फेंक दें। जहां तक ​​मैं समझता हूं कि डेटा को संबंधित होने की गारंटी दी जाती है क्योंकि मैं संबंधित डेटा को फ़िल्टर करने के लिए क्लॉज का उपयोग करता हूं।
मासकप्लान

1
एक हद तक, आप पूरी तरह से सही हैं, आपके द्वारा चुने गए 4 क्षेत्रों में से प्रत्येक उस अधिकतम post_date से संबंधित होगा, लेकिन यह उस प्रश्न का उत्तर नहीं देता है जो पूछा गया था। उदाहरण के लिए, यदि आपने पोस्ट_ड, या पोस्ट की सामग्री जोड़ दी है, तो उन कॉलमों को अधिकतम तिथि के समान रिकॉर्ड से सुनिश्चित नहीं किया जाएगा। पोस्ट के बाकी विवरणों को वापस करने के लिए अपनी क्वेरी को ऊपर लाने के लिए आपको दूसरी क्वेरी चलानी होगी। यदि प्रश्न सबसे हालिया पोस्ट की तिथि को खोजने के बारे में था, तो हाँ आपका उत्तर ठीक होगा।
रोब फॉरेस्ट

@guykaplan, सबक्वेरी धीमी नहीं हैं। डेटा सेट का आकार मायने नहीं रखता। यह इस बात पर निर्भर करता है कि आप इसका उपयोग कैसे करते हैं। देखें percona.com/blog/2010/03/18/when-the-subselect-runs-faster
Pacerier

@ स्पेसर: लेख वास्तव में दिखाता है कि आप उप-प्रश्नों से प्रदर्शन लाभ कैसे प्राप्त कर सकते हैं, लेकिन मैं आपको बेहतर प्रदर्शन करने के लिए दिए गए परिदृश्य को परिवर्तित करते हुए देखना पसंद करूंगा। और डेटा का आकार महत्वपूर्ण है, फिर से आपके द्वारा दिए गए लेख में आप मान रहे हैं कि साथ काम करने के लिए केवल एक तालिका है। डेटा आकार पंक्ति के आकार से नहीं है, जटिलता के आकार से है। कहा जा रहा है कि, यदि आप वास्तव में बड़ी तालिका के साथ काम कर रहे हैं (न कि कई तालिकाओं में) उप-क्वेरी बहुत बेहतर प्रदर्शन कर सकती है।
मर्दकप्लान

-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

जब आप तालिका को ORDER BY में निर्दिष्ट नहीं करते हैं, तो केवल उपनाम, वे चयन के परिणाम का आदेश देंगे।


चयन * की उपेक्षा करें, वे इस उदाहरण में संक्षिप्तता के लिए हैं। आपका जवाब बिल्कुल वैसा ही है जैसा मैंने पहला उदाहरण दिया था।
रोब फॉरेस्ट

उपनाम का कोई प्रभाव नहीं पड़ता है कि कौन सी पंक्ति वापस आती है और न ही परिणामों की छंटाई।
रोब फॉरेस्ट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.