MySQL INNER जॉइन दूसरी तालिका से केवल एक पंक्ति का चयन करें




select inner-join (6)

मेरे पास प्रत्येक उपयोगकर्ता के लिए एक users तालिका और एक payments तालिका है, जिनमें से भुगतान के पास payments तालिका में कई संबंधित भुगतान हो सकते हैं। मैं उन सभी उपयोगकर्ताओं का चयन करना चाहता हूं जिनके पास भुगतान है, लेकिन केवल उनके नवीनतम भुगतान का चयन करें। मैं इस एसक्यूएल की कोशिश कर रहा हूं लेकिन मैंने कभी भी नेस्टेड एसक्यूएल स्टेटमेंट्स की कोशिश नहीं की है, इसलिए मैं जानना चाहता हूं कि मैं क्या गलत कर रहा हूं। मदद की सराहना करें

        SELECT u.* 
            FROM users AS u
            INNER JOIN (
                SELECT p.*
                FROM payments AS p
                ORDER BY date DESC
                LIMIT 1 )
            ON p.user_id = u.id
            WHERE u.package = 1

@ जॉन वू के जवाब ने मुझे एक ही समस्या हल करने में मदद की। मैंने सही क्रम को सेट करके अपने जवाब पर भी सुधार किया है। यह मेरे लिए काम किया है:

SELECT  a.*, c.*
FROM users a 
    INNER JOIN payments c
        ON a.id = c.user_ID
    INNER JOIN (
        SELECT user_ID, MAX(date) as maxDate FROM
        (
            SELECT user_ID, date
            FROM payments
            ORDER BY date DESC
        ) d
        GROUP BY user_ID
    ) b ON c.user_ID = b.user_ID AND
           c.date = b.maxDate
WHERE a.package = 1

मुझे यकीन नहीं है कि यह कितना कुशल है, यद्यपि।


आपकी क्वेरी के साथ दो समस्याएं हैं:

  1. प्रत्येक टेबल और सबक्वायरी को एक नाम की आवश्यकता होती है, इसलिए आपको सबक्वायरी INNER JOIN (SELECT ...) AS p ON ...
  2. जैसा कि आपके पास है, सबक्वायरी केवल एक पंक्ति अवधि देता है, लेकिन आप वास्तव में प्रत्येक उपयोगकर्ता के लिए एक पंक्ति चाहते हैं। इसके लिए आपको अधिकतम तिथि प्राप्त करने के लिए एक प्रश्न की आवश्यकता है और फिर पूरी पंक्ति प्राप्त करने के लिए स्वयं से जुड़ें।

मान लें कि payments.date के लिए कोई संबंध नहीं है, कोशिश करें:

    SELECT u.*, p.* 
    FROM (
        SELECT MAX(p.date) AS date, p.user_id 
        FROM payments AS p
        GROUP BY p.user_id
    ) AS latestP
    INNER JOIN users AS u ON latestP.user_id = u.id
    INNER JOIN payments AS p ON p.user_id = u.id AND p.date = latestP.date
    WHERE u.package = 1

मातेई मिहाई ने एक सरल और कुशल समाधान दिया लेकिन यह तब तक काम नहीं करेगा जब तक कि SELECT भाग में MAX(date) नहीं डालता है, इसलिए यह क्वेरी बन जाएगी:

SELECT u.*, p.*, max(date)
FROM payments p
JOIN users u ON u.id=p.user_id AND u.package = 1
GROUP BY u.id

और ऑर्डर करके ग्रुपिंग में कोई फर्क नहीं पड़ता है लेकिन यह समूह द्वारा प्रदान किए गए अंतिम परिणाम का ऑर्डर कर सकता है। मैंने कोशिश की और यह मेरे लिए काम किया।


मेरा जवाब सीधे @ valex से बहुत उपयोगी है, अगर आपको ऑर्डर द्वारा ऑर्डर में कई कॉल की आवश्यकता है।

    SELECT u.* 
    FROM users AS u
    INNER JOIN (
        SELECT p.*,
         @num := if(@id = user_id, @num + 1, 1) as row_number,
         @id := user_id as tmp
        FROM (SELECT * FROM payments ORDER BY p.user_id ASC, date DESC) AS p,
             (SELECT @num := 0) x,
             (SELECT @id := 0) y
        )
    ON (p.user_id = u.id) and (p.row_number=1)
    WHERE u.package = 1

SELECT u.*, p.*
FROM users AS u
INNER JOIN payments AS p ON p.user_id = u.id AND u.id = (
    SELECT id
    FROM payments AS p2
    WHERE p2.user_id = p.user_id
    ORDER BY date DESC
    LIMIT 1
)

यह समाधान स्वीकार किए गए उत्तर से बेहतर है क्योंकि यह उसी उपयोगकर्ता और दिनांक के साथ कुछ भुगतान होने पर सही तरीके से काम करता है।


SELECT u.*, p.*, max(p.date)
FROM payments p
JOIN users u ON u.id=p.user_id AND u.package = 1
GROUP BY u.id
ORDER BY p.date DESC

इस sqlfiddle





inner-join