2009-05-27 18 views
11

अनिवार्य रूप से मैं इस तरह से कुछ करने की जरूरत है की अद्यतन में चयन नेस्ट .... यह सिर्फ एक उदाहरण है ... लेकिन पहले क्वेरी के सिंटैक्स MySQLmysql एक ही मेज

में
update people set prize = '' 
where prize = 'Gold' and class = (select class from people where id = person_id); 
update people set prize = 'Gold' where id = <id>; 
काम नहीं करता है

किसी भी वर्ग में केवल एक व्यक्ति के पास गोल्ड इनाम हो सकता है। मैं केवल उस व्यक्ति के व्यक्ति_आईडी को जानता हूं जो स्वर्ण पुरस्कार प्राप्त करता है।

मैं पहली पंक्ति में person_id के समान कक्षा में किसी भी पिछले स्वर्ण पुरस्कार विजेताओं को खाली करने की कोशिश कर रहा हूं। फिर दूसरे गोल्ड विजेता को दूसरे में सेट करें।

मेरा मानना ​​है कि मुझे किसी प्रकार के आंतरिक शामिल होने की आवश्यकता है, लेकिन मुझे इस पर 100% निश्चित नहीं है।

यदि मैं एक प्रश्न में पूरी तरह से कर सकता हूं तो भी बेहतर होगा!

कोई भी सलाह दे सकता है?

धन्यवाद :)

उत्तर

7
UPDATE people 
SET prize = CASE WHEN id = @lucky THEN 'Gold' ELSE 'Silver' END 
WHERE class = (
     SELECT class 
     FROM people 
     WHERE id = @lucky 
     ) 

यह एक Silver पुरस्कार के साथ सभी उपयोगकर्ताओं अनुदान देगा, @lucky एक Gold हो जाता है जो छोड़कर।

आप केवल @lucky और पूर्व चैंपियन अद्यतन करने की आवश्यकता है, तो निम्न जारी करते हैं:

UPDATE people 
SET prize = CASE WHEN id = @lucky THEN 'Gold' ELSE 'Silver' END 
WHERE id = @lucky 
     OR (class, prize) = 
     (
     SELECT class, 'Gold' 
     FROM people 
     WHERE id = @lucky 
     ) 
+0

इस सवाल में तैनात रूप में एक ही नहीं करता है। आप कक्षा में प्रत्येक पुरस्कार को "गोल्ड" या "सिल्वर" के साथ ओवरराइड कर रहे हैं, जबकि उपर्युक्त क्वेरी केवल "गोल्ड" पुरस्कार हटाती है और एक नया सेट करती है। उदाहरण: क्या होगा अगर लोगों में से एक का "कांस्य" मूल्य था? – VVS

+0

@ डेविड हिम्पोहल: अच्छा बिंदु, आप क्वेरी के अंत में "WHERE class = 'Gold' या id = @lucky" को जोड़कर ऐसा कर सकते हैं। – Andomar

+0

@ डेविड: @ ओप की क्वेरी वर्ग के भीतर प्रत्येक व्यक्ति के लिए पुरस्कार '' सेट करती है। मैंने सिर्फ पठनीयता – Quassnoi

0

आप निश्चित रूप से एक संग्रहीत प्रक्रिया है कि एक तर्क के रूप में नए पुरस्कार विजेता की आईडी लेता है बना सकते हैं।

फिर आप उस संग्रहित प्रक्रिया को एक पंक्ति में कॉल कर सकते हैं।

CREATE PROC UpdatePrize 
    @newid int 

AS 

UPDATE people 
SET prize = '' 
WHERE prize = 'Gold' 
AND class = (SELECT class 
       FROM people 
       WHERE id = @newid) 

UPDATE people 
SET prize = 'Gold' 
WHERE id = @newid 

GO 
1

आप मामला ऑपरेटर इस्तेमाल कर सकते हैं आप एक ही बयान के बाद कर रहे हैं:

मैं एमएस यहाँ एसक्यूएल लेकिन करने के लिए कुछ इसी तरह का उपयोग कर रहा हूँ? MySQL का उपयोग नहीं किया गया लेकिन कुछ ऐसा:

UPDATE people 
SET prize = CASE 
       WHEN 'Gold' AND id != @newid THEN '' 
       WHEN '' AND id = @newid THEN 'Gold' 
      END 
WHERE class = ( 
       SELECT class 
       FROM people 
       WHERE id = @newid 
      ) 
+0

के लिए 'रजत' के साथ '' 'को प्रतिस्थापित किया है जब' क्या करना चाहिए? हमेशा मेरे सर्वर पर झूठी वापसी करता है। :) – Andomar

+0

आह क्षमा करें, इसका परीक्षण नहीं किया था। आप केस पुरस्कार का उपयोग तब कर सकते हैं जब 'गोल्ड' .... या यदि आपको अभिव्यक्ति का उपयोग करने की आवश्यकता है तो जब पुरस्कार = 'गोल्ड' तब ... जब पुरस्कार = '' फिर .... –

0

चूंकि आप दो अलग-अलग अपडेट कर रहे हैं, इसलिए इसे एक प्रश्न में करने की आवश्यकता नहीं है। यदि आप असंगत डेटा से डरते हैं क्योंकि दो प्रश्नों में से एक विफल हो सकता है, तो आप दो प्रश्नों में से किसी एक के लेन-देन और रोलबैक का उपयोग कर सकते हैं।

आपकी वर्तमान क्वेरी पूरी तरह से पठनीय और समझने योग्य है, जबकि पोस्ट समाधान आसान पठनीय से बहुत दूर हैं।

10

एकल SQL क्वेरी में जटिल अपडेट करना हमेशा सर्वोत्तम नहीं होता है। वास्तव में, यह दो सरल प्रश्नों को चलाने के लिए और अधिक कुशल हो सकता है। तो दोनों समाधानों को बेंचमार्क करना सुनिश्चित करें।

MySQL बहु-तालिका अद्यतन के लिए UPDATE वाक्यविन्यास के विस्तार का समर्थन करता है। आप subqueries का उपयोग करने के बजाय अद्यतन के हिस्से के रूप में JOIN प्रदर्शन कर सकते हैं।

फिर फ़ंक्शन (या CASE) का उपयोग prize मूल्य को सशर्त रूप से अलग-अलग मानों में बदलने के लिए कर सकते हैं।

तो अगर आप पूरी तरह से किसी एक क्वेरी का उपयोग करना चाहिए, कुछ इस तरह का प्रयास करें:

UPDATE people p1 JOIN people p2 
    ON (p1.class = p2.class AND p2.id = <person_id>) 
SET prize = IF(p1.id = <person_id>, 'Gold', '') 
WHERE p1.id = <person_id> OR p1.prize = 'Gold'; 

या इस विकल्प:

UPDATE people p1 JOIN people p2 
    ON (p1.class = p2.class AND p2.id = <person_id>) 
SET p1.prize = CASE 
    WHEN p1.id = <person_id> THEN 'Gold' 
    WHEN p1.prize = 'Gold' THEN '' 
    ELSE p1.prize -- other cases are left as is 
END CASE; 
+0

यह रॉब कांस्य नहीं होगा अपने पदक के पुरस्कार मालिकों? – Andomar

+0

@Andomar: आप सही हैं। मैंने इस जवाब को दिमाग में संपादित किया है। –

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