मैं SQL में किसी अन्य स्तंभ द्वारा MAX (स्तंभ मान), DISTINCT के साथ पंक्तियों का चयन कैसे कर सकता हूं?


767

मेरी तालिका है:

id  home  datetime     player   resource
---|-----|------------|--------|---------
1  | 10  | 04/03/2009 | john   | 399 
2  | 11  | 04/03/2009 | juliet | 244
5  | 12  | 04/03/2009 | borat  | 555
3  | 10  | 03/03/2009 | john   | 300
4  | 11  | 03/03/2009 | juliet | 200
6  | 12  | 03/03/2009 | borat  | 500
7  | 13  | 24/12/2008 | borat  | 600
8  | 13  | 01/01/2009 | borat  | 700

मुझे homeअधिकतम मूल्य रखने वाले प्रत्येक विशिष्ट का चयन करना होगा datetime

परिणाम होगा:

id  home  datetime     player   resource 
---|-----|------------|--------|---------
1  | 10  | 04/03/2009 | john   | 399
2  | 11  | 04/03/2009 | juliet | 244
5  | 12  | 04/03/2009 | borat  | 555
8  | 13  | 01/01/2009 | borat  | 700

मैंने कोशिश की है:

-- 1 ..by the MySQL manual: 

SELECT DISTINCT
  home,
  id,
  datetime AS dt,
  player,
  resource
FROM topten t1
WHERE datetime = (SELECT
  MAX(t2.datetime)
FROM topten t2
GROUP BY home)
GROUP BY datetime
ORDER BY datetime DESC

काम नहीं करता है। परिणाम-सेट में 130 पंक्तियाँ हैं, हालांकि डेटाबेस में 187 हैं। परिणाम में कुछ डुप्लिकेट शामिल हैं home

-- 2 ..join

SELECT
  s1.id,
  s1.home,
  s1.datetime,
  s1.player,
  s1.resource
FROM topten s1
JOIN (SELECT
  id,
  MAX(datetime) AS dt
FROM topten
GROUP BY id) AS s2
  ON s1.id = s2.id
ORDER BY datetime 

नहीं। सारे रिकॉर्ड देता है।

-- 3 ..something exotic: 

विभिन्न परिणामों के साथ।

जवाबों:


938

तुम इतने करीब हो! आपको बस घर और उसके अधिकतम तिथि समय का चयन करना है, फिर वापस toptenबीओटीएच फ़ील्ड पर तालिका में शामिल हों :

SELECT tt.*
FROM topten tt
INNER JOIN
    (SELECT home, MAX(datetime) AS MaxDateTime
    FROM topten
    GROUP BY home) groupedtt 
ON tt.home = groupedtt.home 
AND tt.datetime = groupedtt.MaxDateTime

5
इसे अलग से टेस्ट करें, यदि दो समान अधिकतम डेटाइम एक ही घर में हों (अलग-अलग खिलाड़ियों के साथ)
मेक्सिकम गोन्टर

5
मुझे लगता है कि ऐसा करने का क्लासिक तरीका प्राकृतिक जुड़ाव के साथ है: "SELt tt। समान रूप से क्वेरी, लेकिन यकीनन अधिक पठनीय
पार्कर

31
क्या होगा अगर दो पंक्तियाँ हैं जिनमें समान 'होम' और 'डेटाइम' फ़ील्ड मान हैं?
केमल दुरान

3
@ आपकी क्वेरी के साथ समस्या यह है कि यह वापस आ सकती है id, playerऔर resourceकिसी दिए गए घर के लिए गैर-अधिकतम पंक्ति यानी घर के लिए = 10 आपको मिल सकती है: 3 | 10 | 04/03/2009 | john | 300 दूसरे शब्दों में यह गारंटी नहीं देता है कि परिणाम में एक पंक्ति के सभी कॉलम संबंधित होंगे अधिकतम (डेटाटाइम) दिए गए घर के लिए।
12

1
@ me1111 आपकी क्वेरी के साथ समस्या यह है कि यह दिए गए घर के लिए पंक्ति ith मैक्स (डेटाइम) को वापस नहीं कर सकता है। कारण यह है कि ग्रुप BY प्रत्येक घर के लिए कोई भी यादृच्छिक पंक्ति
लाएगा

87

सबसे तेज MySQLसमाधान, आंतरिक प्रश्नों के बिना और बिना GROUP BY:

SELECT m.*                    -- get the row that contains the max value
FROM topten m                 -- "m" from "max"
    LEFT JOIN topten b        -- "b" from "bigger"
        ON m.home = b.home    -- match "max" row with "bigger" row by `home`
        AND m.datetime < b.datetime           -- want "bigger" than "max"
WHERE b.datetime IS NULL      -- keep only if there is no bigger than max

स्पष्टीकरण :

homeस्तंभ का उपयोग करके अपने आप से तालिका में शामिल हों । परिणाम सेट में LEFT JOINतालिका से सभी पंक्तियों का उपयोग mदिखाई देता है। जिनके पास तालिका में मेल नहीं है , के कॉलम के लिए s bहोगा ।NULLb

दूसरी JOINपंक्तियों पर bउस पंक्ति से मिलान करने के लिए कहता है जिसमें datetimeस्तंभ पर पंक्ति से बड़ा मान है m

प्रश्न में पोस्ट किए गए डेटा का उपयोग करके, LEFT JOINइस जोड़े का उत्पादन करेगा:

+------------------------------------------+--------------------------------+
|              the row from `m`            |    the matching row from `b`   |
|------------------------------------------|--------------------------------|
| id  home  datetime     player   resource | id    home   datetime      ... |
|----|-----|------------|--------|---------|------|------|------------|-----|
| 1  | 10  | 04/03/2009 | john   | 399     | NULL | NULL | NULL       | ... | *
| 2  | 11  | 04/03/2009 | juliet | 244     | NULL | NULL | NULL       | ... | *
| 5  | 12  | 04/03/2009 | borat  | 555     | NULL | NULL | NULL       | ... | *
| 3  | 10  | 03/03/2009 | john   | 300     | 1    | 10   | 04/03/2009 | ... |
| 4  | 11  | 03/03/2009 | juliet | 200     | 2    | 11   | 04/03/2009 | ... |
| 6  | 12  | 03/03/2009 | borat  | 500     | 5    | 12   | 04/03/2009 | ... |
| 7  | 13  | 24/12/2008 | borat  | 600     | 8    | 13   | 01/01/2009 | ... |
| 8  | 13  | 01/01/2009 | borat  | 700     | NULL | NULL | NULL       | ... | *
+------------------------------------------+--------------------------------+

अंत में, WHEREक्लॉज केवल उन जोड़ियों को रखता है, जिनके NULLकॉलम में एस b(वे *ऊपर तालिका में चिह्नित हैं ); इसका अर्थ है, JOINखंड से दूसरी स्थिति के कारण , चयनित पंक्ति से mस्तंभ में सबसे बड़ा मान है datetime

SQL एंटीपार्टर्न पढ़ें : अन्य SQL टिप्स के लिए डेटाबेस प्रोग्रामिंग बुक के नुकसान से बचना


के साथ SQLite, पहला वाला ला वोई के संस्करण की तुलना में बहुत धीमा है जब मिलान किए गए कॉलम (यानी "घर") पर कोई सूचकांक नहीं है। (13k पंक्तियों में जिसके परिणामस्वरूप 24k पंक्तियों के साथ परीक्षण किया गया है)
थॉमस टेम्पेलमैन

10
यह सबसे अच्छा उत्तर है, यदि आप निष्पादन योजना दिखाते हैं तो आपको इस प्रश्न के साथ एक कदम कम दिखाई देगा
TlmaK0

अगर 2 पंक्तियाँ एक ही है कि क्या होगा homeऔर datetimeऔर datetimeउस विशेष के लिए अधिकतम है home?
१२:०४ पर इस्तियाक अहमद '’

परिणाम सेट में दोनों पंक्तियाँ दिखाई देती हैं। यह उत्तर अवधारणा का प्रमाण है। आपके वास्तविक कोड में, संभवतः आपके पास इस स्थिति में उनमें से केवल एक का चयन करने के लिए एक और मानदंड है (शायद पहले एक या अंतिम एक या आप निर्णय लेने के लिए किसी अन्य स्तंभ का उपयोग करें)। इस मानदंड को ONखंड में एक नई शर्त के रूप में जोड़ें । Fe ... ON ... AND m.id < b.idसबसे हाल की प्रविष्टि (सबसे बड़ी के साथ एक id) रखने के लिए जब दो पंक्तियों में homeऔर datetimeकॉलम में समान मान होते हैं और यह अधिकतम है datetime
13

इस तरह से क्वेरी के लिए कौन से इंडेक्स सबसे अच्छा ऑप्टिमाइज़ करेंगे?
AjaxLeung

73

यहाँ T-SQL संस्करण जाता है :

-- Test data
DECLARE @TestTable TABLE (id INT, home INT, date DATETIME, 
  player VARCHAR(20), resource INT)
INSERT INTO @TestTable
SELECT 1, 10, '2009-03-04', 'john', 399 UNION
SELECT 2, 11, '2009-03-04', 'juliet', 244 UNION
SELECT 5, 12, '2009-03-04', 'borat', 555 UNION
SELECT 3, 10, '2009-03-03', 'john', 300 UNION
SELECT 4, 11, '2009-03-03', 'juliet', 200 UNION
SELECT 6, 12, '2009-03-03', 'borat', 500 UNION
SELECT 7, 13, '2008-12-24', 'borat', 600 UNION
SELECT 8, 13, '2009-01-01', 'borat', 700

-- Answer
SELECT id, home, date, player, resource 
FROM (SELECT id, home, date, player, resource, 
    RANK() OVER (PARTITION BY home ORDER BY date DESC) N
    FROM @TestTable
)M WHERE N = 1

-- and if you really want only home with max date
SELECT T.id, T.home, T.date, T.player, T.resource 
    FROM @TestTable T
INNER JOIN 
(   SELECT TI.id, TI.home, TI.date, 
        RANK() OVER (PARTITION BY TI.home ORDER BY TI.date) N
    FROM @TestTable TI
    WHERE TI.date IN (SELECT MAX(TM.date) FROM @TestTable TM)
)TJ ON TJ.N = 1 AND T.id = TJ.id

संपादित करें
दुर्भाग्य से, MySQL में कोई RANK () OVER फ़ंक्शन नहीं है।
लेकिन इसका अनुकरण किया जा सकता है, MySQL के साथ Eminating विश्लेषणात्मक (AKA रैंकिंग) कार्य देखें
तो यह MySQL संस्करण है:

SELECT id, home, date, player, resource 
FROM TestTable AS t1 
WHERE 
    (SELECT COUNT(*) 
            FROM TestTable AS t2 
            WHERE t2.home = t1.home AND t2.date > t1.date
    ) = 0

सॉरी यार, # 1064 - आपके एसक्यूएल सिंटैक्स में एक त्रुटि है; उस मैनुअल की जाँच करें जो आपके MySQL सर्वर संस्करण के समीप के वाक्य विन्यास का उपयोग करता है '() OVER (PARTITION BY krd ORDER BY daytime DESC) N FROM @rapsa) M WHERE N =' पंक्ति 1 पर
Kaptah

2
आह, तो आप MySQL का उपयोग कर रहे हैं। यही से आपको शुरू करना चाहिए! मैं जल्द ही जवाब अपडेट कर दूंगा।
मैक्सिमम गोन्टर

@MaxGontar, अपने mysql समाधान चट्टानों, thx। क्या होगा यदि आपके @_TestTable में आप पंक्ति # 1>: SELECT 1, 10, '2009-03-04', 'जॉन', 399 का चयन करते हैं, यह है, यदि आपके पास किसी दिए गए गृह मान के लिए एक पंक्ति है तो क्या होगा? धन्यवाद।
egidiocs

2
बग: "ROW_NUMBER ()" के साथ "RANK ()" को बदलें। यदि आपके पास एक टाई है (एक डुप्लिकेट डेट वैल्यू के कारण) तो आपके पास N. के लिए "1" के साथ दो रिकॉर्ड होंगे
माइकटीवीवी

29

यह तब भी काम करेगा जब आपके पास homeसमान के साथ प्रत्येक के लिए दो या अधिक पंक्तियाँ हों DATETIME:

SELECT id, home, datetime, player, resource
FROM   (
       SELECT (
              SELECT  id
              FROM    topten ti
              WHERE   ti.home = t1.home
              ORDER BY
                      ti.datetime DESC
              LIMIT 1
              ) lid
       FROM   (
              SELECT  DISTINCT home
              FROM    topten
              ) t1
       ) ro, topten t2
WHERE  t2.id = ro.lid

तालिका में ढक्कन क्षेत्र जोड़ा गया, कोई अच्छा
कपाटा

1
यह एक PHPMyAdmin पर निष्पादित नहीं किया। पृष्ठ रीफ़्रेश होता है लेकिन कोई परिणाम नहीं होता है और न ही त्रुटि ..?
कपाटह 24:09

WHERE ti.home = t1.home- क्या आप वाक्यविन्यास समझा सकते हैं?
इस्तियाक अहमद

@IstiaqueAhmed: क्या वास्तव में यह है कि आप यहाँ समझ नहीं है? यह एक सहसंबद्ध क्वेरी है, और आपके द्वारा उल्लिखित अभिव्यक्ति एक सहसंबंध स्थिति है।
क्वासोनी

@Quassnoi, जिस selectक्वेरी में लाइन WHERE ti.home = t1.home है उसे FROMपरिभाषित करने वाले क्लॉज़ की आवश्यकता नहीं है t1। तो इसका उपयोग कैसे किया जाता है?
इस्तियाक अहमद

26

मुझे लगता है कि यह आपको वांछित परिणाम देगा:

SELECT   home, MAX(datetime)
FROM     my_table
GROUP BY home

लेकिन अगर आपको अन्य कॉलमों की भी आवश्यकता है, तो बस मूल तालिका (चेक Michael La Voieउत्तर) के साथ जुड़ें

सादर।


8
उसे अन्य कॉलम भी चाहिए।
क्वासोनी

4
आईडी, घर,
डेटाटाइम

17

चूंकि लोग इस धागे में चलते रहते हैं (टिप्पणी की तिथि 1.5 वर्ष से है) यह बहुत सरल नहीं है:

SELECT * FROM (SELECT * FROM topten ORDER BY datetime DESC) tmp GROUP BY home

कोई एकत्रीकरण कार्यों की आवश्यकता ...

चीयर्स।


6
यह काम नहीं लगता है। त्रुटि संदेश: कॉलम 'x' चुनिंदा सूची में अमान्य है क्योंकि यह एक समुच्चय फ़ंक्शन या ग्रुप बाय क्लॉज़ में निहित नहीं है।
फॉउल

यह निश्चित रूप से SQL सर्वर या Oracle में काम नहीं करेगा, हालांकि ऐसा लगता है कि यह MySQL में काम कर सकता है।
एरिक

यह वास्तव में सुंदर है! यह कैसे काम करता है? DESC और डिफ़ॉल्ट समूह रिटर्न कॉलम का उपयोग करके? इसलिए अगर मैंने इसे एएससीटाइम एएससी में बदल दिया, तो यह प्रत्येक घर के लिए सबसे पहली पंक्ति लौटाएगा?
वेफ्टोफाइन्मेंट

ये जबरदस्त है!
डॉग लवर

यदि आपके पास (MySQL में) गैर-पृथक कॉलम हैं, तो यह सीधे काम नहीं करता है।
user3562927

11

आप इसे भी आज़मा सकते हैं और बड़े तालिकाओं के लिए क्वेरी प्रदर्शन बेहतर होगा। यह तब काम करता है जब प्रत्येक घर के लिए दो से अधिक रिकॉर्ड नहीं होते हैं और उनकी तिथियां अलग होती हैं। बेहतर सामान्य MySQL क्वेरी ऊपर माइकल ला Voie से एक है।

SELECT t1.id, t1.home, t1.date, t1.player, t1.resource
FROM   t_scores_1 t1 
INNER JOIN t_scores_1 t2
   ON t1.home = t2.home
WHERE t1.date > t2.date

या Postgres या उन dbs के मामले में जो विश्लेषणात्मक कार्य प्रदान करते हैं

SELECT t.* FROM 
(SELECT t1.id, t1.home, t1.date, t1.player, t1.resource
  , row_number() over (partition by t1.home order by t1.date desc) rw
 FROM   topten t1 
 INNER JOIN topten t2
   ON t1.home = t2.home
 WHERE t1.date > t2.date 
) t
WHERE t.rw = 1

क्या यह उत्तर सही है? मैंने इसका उपयोग करने की कोशिश की, लेकिन यह 'घर' के लिए नवीनतम तारीख के साथ रिकॉर्ड का चयन नहीं करने के लिए सीम करता है, लेकिन केवल सबसे पुरानी तारीख के साथ रिकॉर्ड को हटा देता है। यहाँ एक उदाहरण है: SQLfiddle
marcin93w

1
@kidOfDeath - मेरे उत्तर को संदर्भ के साथ अपडेट करें और क्वेरी
शिव

के साथ SQLite, पहला वाला ला वोई के संस्करण की तुलना में बहुत धीमा है जब मिलान किए गए कॉलम (यानी "घर") पर कोई सूचकांक नहीं है।
थॉमस टेंपलमैन

8

यह ओरेकल पर काम करता है:

with table_max as(
  select id
       , home
       , datetime
       , player
       , resource
       , max(home) over (partition by home) maxhome
    from table  
)
select id
     , home
     , datetime
     , player
     , resource
  from table_max
 where home = maxhome

1
यह अधिकतम डेटाटाइम कैसे चुनता है? उन्होंने घर से समूह बनाने के लिए कहा, और अधिकतम डेटाटाइम का चयन करें। मैं नहीं देखता कि यह कैसे करता है।
n00b

8
SELECT  tt.*
FROM    TestTable tt 
INNER JOIN 
        (
        SELECT  coord, MAX(datetime) AS MaxDateTime 
        FROM    rapsa 
        GROUP BY
                krd 
        ) groupedtt
ON      tt.coord = groupedtt.coord
        AND tt.datetime = groupedtt.MaxDateTime

8

SQL सर्वर के लिए यह प्रयास करें:

WITH cte AS (
   SELECT home, MAX(year) AS year FROM Table1 GROUP BY home
)
SELECT * FROM Table1 a INNER JOIN cte ON a.home = cte.home AND a.year = cte.year

5
SELECT c1, c2, c3, c4, c5 FROM table1 WHERE c3 = (select max(c3) from table)

SELECT * FROM table1 WHERE c3 = (select max(c3) from table1)

5

यहाँ MySQL संस्करण है जो केवल एक प्रविष्टि को प्रिंट करता है जहाँ एक समूह में MAX (डेटाटाइम) डुप्लिकेट हैं।

आप यहां परीक्षण कर सकते हैं http://www.sqlfiddle.com/# -2/0a4ae/1 का

नमूना डेटा

mysql> SELECT * from topten;
+------+------+---------------------+--------+----------+
| id   | home | datetime            | player | resource |
+------+------+---------------------+--------+----------+
|    1 |   10 | 2009-04-03 00:00:00 | john   |      399 |
|    2 |   11 | 2009-04-03 00:00:00 | juliet |      244 |
|    3 |   10 | 2009-03-03 00:00:00 | john   |      300 |
|    4 |   11 | 2009-03-03 00:00:00 | juliet |      200 |
|    5 |   12 | 2009-04-03 00:00:00 | borat  |      555 |
|    6 |   12 | 2009-03-03 00:00:00 | borat  |      500 |
|    7 |   13 | 2008-12-24 00:00:00 | borat  |      600 |
|    8 |   13 | 2009-01-01 00:00:00 | borat  |      700 |
|    9 |   10 | 2009-04-03 00:00:00 | borat  |      700 |
|   10 |   11 | 2009-04-03 00:00:00 | borat  |      700 |
|   12 |   12 | 2009-04-03 00:00:00 | borat  |      700 |
+------+------+---------------------+--------+----------+

उपयोगकर्ता चर के साथ MySQL संस्करण

SELECT *
FROM (
    SELECT ord.*,
        IF (@prev_home = ord.home, 0, 1) AS is_first_appear,
        @prev_home := ord.home
    FROM (
        SELECT t1.id, t1.home, t1.player, t1.resource
        FROM topten t1
        INNER JOIN (
            SELECT home, MAX(datetime) AS mx_dt
            FROM topten
            GROUP BY home
          ) x ON t1.home = x.home AND t1.datetime = x.mx_dt
        ORDER BY home
    ) ord, (SELECT @prev_home := 0, @seq := 0) init
) y
WHERE is_first_appear = 1;
+------+------+--------+----------+-----------------+------------------------+
| id   | home | player | resource | is_first_appear | @prev_home := ord.home |
+------+------+--------+----------+-----------------+------------------------+
|    9 |   10 | borat  |      700 |               1 |                     10 |
|   10 |   11 | borat  |      700 |               1 |                     11 |
|   12 |   12 | borat  |      700 |               1 |                     12 |
|    8 |   13 | borat  |      700 |               1 |                     13 |
+------+------+--------+----------+-----------------+------------------------+
4 rows in set (0.00 sec)

स्वीकृत उत्तर 'आउटआउट'

SELECT tt.*
FROM topten tt
INNER JOIN
    (
    SELECT home, MAX(datetime) AS MaxDateTime
    FROM topten
    GROUP BY home
) groupedtt ON tt.home = groupedtt.home AND tt.datetime = groupedtt.MaxDateTime
+------+------+---------------------+--------+----------+
| id   | home | datetime            | player | resource |
+------+------+---------------------+--------+----------+
|    1 |   10 | 2009-04-03 00:00:00 | john   |      399 |
|    2 |   11 | 2009-04-03 00:00:00 | juliet |      244 |
|    5 |   12 | 2009-04-03 00:00:00 | borat  |      555 |
|    8 |   13 | 2009-01-01 00:00:00 | borat  |      700 |
|    9 |   10 | 2009-04-03 00:00:00 | borat  |      700 |
|   10 |   11 | 2009-04-03 00:00:00 | borat  |      700 |
|   12 |   12 | 2009-04-03 00:00:00 | borat  |      700 |
+------+------+---------------------+--------+----------+
7 rows in set (0.00 sec)

एल्थो मैं इस जवाब से प्यार करता हूं, क्योंकि यह मुझे बहुत मदद कर रहा है, मुझे एक बड़ी खामी की ओर इशारा करना है, यह कि यह Mysql प्रणाली पर निर्भर है। मूल रूप से, यह समाधान अवशिष्ट में खंड द्वारा ORDER पर निर्भर करता है। यह मैट्स, या MIGHT विभिन्न mysql वातावरण में काम नहीं करती है। मैंने इसे शुद्ध MySQL पर आज़माया नहीं है, लेकिन यह सुनिश्चित करने के लिए कि यह MariaDB 10.1 पर RELIABLY काम नहीं करता है, जैसा कि यहां बताया गया है stackoverflow.com/questions/26372511/… लेकिन Percona सर्वर पर बहुत ही कोड ठीक काम नहीं करता है। सटीक होने के लिए, आप T1 कॉलम की मात्रा के आधार पर एक ही परिणाम प्राप्त नहीं कर सकते हैं।
राडेक

इस कथन के लिए उदाहरण यह है कि MariaDB 10.1 पर यह काम किया, जब मैंने t1 तालिका से 5 कॉलम का उपयोग किया। जैसे ही मैंने छठा स्तंभ जोड़ा, स्पष्ट रूप से मूल तालिका में "प्राकृतिक" डेटा सॉर्ट के साथ खिलवाड़ हुआ, इसने काम करना बंद कर दिया। इसका कारण यह है कि सबसेलेक्ट में डेटा अन-ऑर्डर हो गया और इस तरह मेरे पास "is_first_appear = 1" स्थिति कई बार मिली। समान डेटा वाला समान कोड, पेरकोना ओके पर काम करता है।
राडेक

5

उप-क्वेरी का उपयोग करके प्रति समूह सबसे हाल की पंक्ति को gt के लिए एक और तरीका है जो मूल रूप से प्रति समूह प्रत्येक पंक्ति के लिए एक रैंक की गणना करता है और फिर रैंक = 1 के साथ अपनी सबसे हालिया पंक्तियों को फ़िल्टर करता है।

select a.*
from topten a
where (
  select count(*)
  from topten b
  where a.home = b.home
  and a.`datetime` < b.`datetime`
) +1 = 1

डेमो

यहाँ बेहतर समझ के लिए प्रत्येक पंक्ति के लिए रैंक नं के लिए दृश्य डेमो है

कुछ टिप्पणियों को पढ़ने से क्या होगा अगर दो पंक्तियाँ हैं जिनमें समान 'होम' और 'डेटाइम' फ़ील्ड मान हैं?

उपरोक्त क्वेरी विफल हो जाएगी और उपरोक्त स्थिति के लिए 1 से अधिक पंक्तियों को वापस कर देगी। इस स्थिति को कवर करने के लिए एक और मानदंड / पैरामीटर / कॉलम की आवश्यकता होगी जो यह तय करे कि कौन सी पंक्ति लेनी चाहिए जो उपरोक्त स्थिति में आती है। नमूना डेटा सेट को देखकर मुझे लगता है कि एक प्राथमिक कुंजी स्तंभ है idजिसे ऑटो वेतन वृद्धि के लिए सेट किया जाना चाहिए। इसलिए हम इस कॉलम का उपयोग CASEस्टेटमेंट की मदद से एक ही क्वेरी को ट्विक करके सबसे हालिया पंक्ति को लेने के लिए कर सकते हैं

select a.*
from topten a
where (
  select count(*)
  from topten b
  where a.home = b.home
  and  case 
       when a.`datetime` = b.`datetime`
       then a.id < b.id
       else a.`datetime` < b.`datetime`
       end
) + 1 = 1

डेमो

ऊपर क्वेरी उसी के बीच उच्चतम आईडी के साथ पंक्ति उठाएगी datetime मानों के चुनेगी

प्रत्येक पंक्ति के लिए रैंक नं के लिए दृश्य डेमो


2

क्यों नहीं उपयोग करें: घर का चयन करें, मैक्स (डेटाइम) एएस मैक्सडाइमटाइम, खिलाड़ी, संसाधन से घर से ग्रुप बनाएं क्या मुझे कुछ याद आया?


4
यह केवल MySQL के साथ मान्य होगा, और केवल 5.7 से पहले के संस्करण (?) या 5.7 के बाद ONLY_FULL_GROUP_BY अक्षम होने के बाद, क्योंकि यह उन स्तंभों का चयन कर रहा है जिन्हें एकत्रित / समूहित (खिलाड़ी, संसाधन) नहीं किया गया है, जो MySQL उन लोगों के लिए यादृच्छिक रूप से चुने हुए मान प्रदान करेगा दो परिणाम क्षेत्र। खिलाड़ी कॉलम के लिए यह समस्या नहीं होगी क्योंकि यह होम कॉलम से संबंधित है, लेकिन संसाधन कॉलम होम या डेटाटाइम कॉलम से संबद्ध नहीं होगा और आप यह गारंटी नहीं दे सकते कि आपको कौन सा संसाधन मान प्राप्त होगा।
साधारण

स्पष्टीकरण के लिए +1, BUT ने यह प्रश्न पूछा कि यह क्वेरी expectedMySQL संस्करण 5.6 में आउटपुट नहीं लौटाएगी beforeऔर मुझे अत्यधिक संदेह है कि यह अन्यथा MySQL संस्करण 5.7 और में व्यवहार करता है after
13 अक्टूबर को sactiw

@ सिम्पलसुअर, `यह खिलाड़ी स्तंभ के लिए एक समस्या नहीं होगी क्योंकि यह घर स्तंभ से संबंधित है '- क्या आप इसे और अधिक समझा सकते हैं?
इस्तियाक अहमद

@IstiaqueAhmed जैसा कि मैं इसे फिर से देखता हूं, यह कथन गलत है। मैंने सोचा था कि प्रत्येक खिलाड़ी के पास हमेशा एक ही घर का मूल्य होता है, लेकिन मैं अब देखता हूं कि वे नहीं करते हैं, इसलिए उस कॉलम के लिए भी एक ही यादृच्छिक चयन समस्या उत्पन्न होगी
simpleuser

1

इसे इस्तेमाल करे

select * from mytable a join
(select home, max(datetime) datetime
from mytable
group by home) b
 on a.home = b.home and a.datetime = b.datetime

सादर के


5
इसे अलग से टेस्ट करें, अगर दो समान अधिकतम डेटाइम एक ही घर में हों (अलग-अलग खिलाड़ियों के साथ)
मेक्सिम गोन्टर

के लिए उपनाम max(datetime) है datetime। क्या इससे कोई समस्या नहीं होगी?
इस्तियाक अहमद

उच्चतम का datetimeचयन कैसे किया जाता है ?
इस्तियाक अहमद

1

यह वह क्वेरी है जिसकी आपको आवश्यकता है:

 SELECT b.id, a.home,b.[datetime],b.player,a.resource FROM
 (SELECT home,MAX(resource) AS resource FROM tbl_1 GROUP BY home) AS a

 LEFT JOIN

 (SELECT id,home,[datetime],player,resource FROM tbl_1) AS b
 ON  a.resource = b.resource WHERE a.home =b.home;

क्या आप अपना उत्तर बता सकते हैं?
इस्तियाक अहमद

1

@ मिचाए स्वीकार किए गए जवाब ज्यादातर मामलों में ठीक काम करेंगे लेकिन यह नीचे के रूप में एक के लिए विफल है।

यदि होमआईडी और डेटाइम वाली 2 पंक्तियाँ थीं, तो क्वेरी दोनों पंक्तियों को वापस लाएगी, न कि अलग-अलग होमआईडी को, जैसा कि आवश्यक है, इसके लिए नीचे दिए अनुसार क्वेरी में डिस्टिंक जोड़ें।

SELECT DISTINCT tt.home  , tt.MaxDateTime
FROM topten tt
INNER JOIN
    (SELECT home, MAX(datetime) AS MaxDateTime
    FROM topten
    GROUP BY home) groupedtt 
ON tt.home = groupedtt.home 
AND tt.datetime = groupedtt.MaxDateTime

परिणाम दिखाता है - "# 1054 - अज्ञात कॉलम 'tt.MaxDateTime' को 'फ़ील्ड सूची' में"
इस्तियाक अहमद

@IstiaqueAhmed क्या आपके पास मैक्सडाइमटाइम दायर किया गया है अर्थात ऐसा कोई भी कॉलम नाम ..?
मनोज कारगेटी Man

नहीं, OP की तालिका में ऐसा कोई कॉलम नहीं है।
इस्तियाक अहमद

त्रुटि भी एक ही कृपया कह रही है..क्या आप वास्तव में करना चाहते हैं? क्या आप टेबल संरचना और अपनी क्वेरी भेज सकते हैं।
मनोज कारगेटी

1

क्वेरी से नीचे की उम्मीद वांछित आउटपुट देगी:

Select id, home,datetime,player,resource, row_number() over (Partition by home ORDER by datetime desc) as rownum from tablename where rownum=1
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.