2013-08-16 7 views
5

जरूरत है मैं एक प्रश्न जो की तरहmysql क्वेरी अनुकूलन की

id | productid | userid | coinsid 
1 | 2   | 2  | 5  
3 | 2   | 2  | 6  
4 | 2   | 3  | 7 
5 | 2   | 4  | 8 
6 | 2   | 3  | 9 

इस विशिष्ट productid के लिए परिणाम है परिणाम दे दिया है। अब मुझे उपरोक्त परिणामों में सभी उपयोगकर्ताओं को $ 1 जोड़कर user table में शेष राशि अपडेट करनी है, लेकिन यदि userid दो बार है, तो मुझे उस विशिष्ट उपयोगकर्ता के शेष में $ 1 दो बार जोड़ना होगा। तो उपर्युक्त मामले में $ 1 दो बार userid=2 संतुलन और userid=3 शेष में जोड़ा गया।

सरल तरीका प्रत्येक विशिष्ट userid के लिए रिकॉर्ड गिनना है और हमारे पास foreach लूप में उपयोगकर्ता के रूप में कई बार क्वेरी चलाएं। लेकिन मैं कुछ अनुकूल तरीका ढूंढ रहा हूं। कृपया कोई सुझाव दें। धन्यवाद

+0

उपयोगकर्ता आईडी और क्वेरी सिक्का आईडी द्वारा क्वेरी के परिणामों को समूहित करें उपयोगकर्ता आईडी की गिनती के लिए एक कॉलम जोड़ें अपने $ 1 द्वारा उपयोगकर्ता आईडी की गिनती गुणा करें और सिक्कों को अपडेट करें उस नए मान के साथ। – xQbert

+0

@AliBZ, हां 'बैलेंस' उपयोगकर्ता तालिका में कॉलम नाम है। जहां मुझे संतुलन अपडेट करना है। –

+0

क्षमा करें, मेरा बुरा, मुझे वह हिस्सा याद आया। – AliBZ

उत्तर

4

एक दृष्टिकोण:

UPDATE user_table u 
    JOIN (SELECT q.userid 
       , SUM(1.00) AS deposit 
      FROM (
        -- original OP query goes here 
       ) q 
      GROUP BY q.userid 
     ) r 
    ON r.userid = u.userid 
    SET u.balance = u.balance + r.deposit 

हम मूल ओपी क्वेरी कि resultset दिखाया गया रिटर्न का उपयोग करें और बनाने है कि (जैसा कि ऊपर के रूप में क्ष क्वेरी में एलियास) एक इनलाइन दृश्य।

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

हम चाहते हैं कि इनलाइन दृश्य (आर) उपयोगकर्ता तालिका में शामिल होने, और है कि उपयोगकर्ता (बैलेंस संभालने के लिए वर्तमान शेष के लिए जमा राशि जोड़, दशमलव डॉलर के रूप में संग्रहीत किया जाता है (1।00 = एक डॉलर)


परीक्षण करने के लिए, एक SELECT बयान में UPDATE कन्वर्ट:

  • "SET" खंड
  • को दूर एक "ORDER BY" खंड जोड़ने (वैकल्पिक) बनाने के लिए परिणाम
  • "UPDATE" कीवर्ड को हटाएं और इसे
को बदलें साथ

:

SELECT r.userid 
     , r.deposit 
     , u.balance    AS old_balance 
     , u.balance + r.deposit AS new_balance 
     , u.userid 
    FROM 

पूर्ण चयन:

SELECT r.userid 
     , r.deposit 
     , u.balance    AS old_balance 
     , u.balance + r.deposit AS new_balance 
     , u.userid 
    FROM user_table u 
    JOIN (SELECT q.userid 
       , SUM(1.00) AS deposit 
      FROM (
        -- original OP query goes here 
       ) q 
      GROUP BY q.userid 
     ) r 
    ON r.userid = u.userid 

नोट कोई है कहां खंड, शामिल हों विधेय (ON खंड में) क्या निर्धारित करता है जो पंक्तियां चयनित हैं है/उपयोगकर्ता तालिका में प्रभावित।

+0

(पहले शामिल मानदंडों को खोना ... DOH! तय। – spencer7593

+0

आपकी प्रतिक्रिया के लिए धन्यवाद। मैंने कोशिश की, और यह मेरे लिए बैलेंस अपडेट किया गया लेकिन दुर्भाग्यवश सभी उपयोगकर्ताओं के लिए अपडेट की गई शेष राशि, क्या हमें अपडेट क्वेरी के अंत में क्लॉज की आवश्यकता है? –

+0

अब पूरी तरह से काम किया है। मुझे कई उपयोगकर्ताओं पर आज़माएं :) –

0
select count(*), userid from yourTable group by userid 

यदि मैं आपका प्रश्न समझता हूं।

1

मान लिया जाये कि आप अपनी शेष राशि तालिका में कोई डुप्लिकेट उपयोगकर्ता आईडी है, हो सकता है कुछ इस तरह काम करेगा:

update balance_table set balance_table.balance = (select count(*) from users_table where users_table.user_id = balance_table.user_id) * 1; 

मैं एक mysql डेटाबेस के खिलाफ इस क्वेरी प्रयास नहीं किया है के रूप में मैं plsql से अधिक परिचित हूँ, लेकिन इस काम की तरह कुछ नहीं होगा?

+0

इस मामले में * 1 इसलिए है क्योंकि आप प्रति उपयोगकर्ता अवसर 1 डॉलर जोड़ना चाहते हैं, लेकिन किसी भी राशि में बदला जा सकता है। – schwarz

+0

डुप्लिकेट नहीं बल्कि एकाधिक उपयोगकर्ता आईडी है, इसलिए यह मुझे लगता है कि यह काम नहीं करेगा। –

1

दूसरे उत्तर में सहसंबंधित सबक्वायरी काम करेगी, लेकिन एक इंटर्न जॉइन आमतौर पर अधिक कुशल होगा। इस तरह कुछ कोशिश करो; आपको निश्चित रूप से टेबल और कॉलम नामों की आपूर्ति करने की आवश्यकता होगी।

UPDATE myTable 
INNER JOIN (
    SELECT userid, count(*) AS AmountToAdd 
    FROM users 
    GROUP BY userid 
) UserCounts ON myTable.userid = UserCounts.userid 
SET balance = balance + UserCounts.AmountToAdd 
+0

यह एक व्यावहारिक दृष्टिकोण है। लेकिन इस क्वेरी में इनलाइन व्यू 'उपयोगकर्ताओं से' है, लेकिन ओपी ने संकेत दिया कि उपयोगकर्ताओं की सूची एक प्रश्न का परिणाम थी (क्वेरी का वास्तविक पाठ नहीं दिया गया था।) इसलिए ओपी को 'उपयोगकर्ताओं से' 'से चुनें (चुनें/* मूल क्वेरी * /) उपनाम '। जब भी एक क्वेरी में संदर्भित एक से अधिक तालिका होती है, तो सर्वोत्तम अभ्यास सभी कॉलम संदर्भों को अर्हता प्राप्त करना है। – spencer7593

संबंधित मुद्दे