2012-11-30 20 views
67

के साथ एसक्यूएल अपडेट मैं एक वृद्धिशील संख्या के साथ अपना कॉलम CODE_DEST अपडेट करना चाहता हूं। मेरे पास है:row_number()

UPDATE DESTINATAIRE_TEMP 
SET CODE_DEST = TheId 
FROM (SELECT Row_Number() OVER (ORDER BY [RS_NOM]) AS TheId FROM DESTINATAIRE_TEMP) 

यह )

की वजह से काम नहीं करता है:

CODE_DEST RS_NOM 
1   qsdf 
2   sdfqsdfqsdf 
3   qsdfqsdf 

मैं इस कोड की कोशिश की है:

CODE_DEST RS_NOM 
null  qsdf 
null  sdfqsdfqsdf 
null  qsdfqsdf 

मैं चाहूँगा इसे होने की अद्यतन करने के लिए

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

WITH DESTINATAIRE_TEMP AS 
    (
    SELECT 
    ROW_NUMBER() OVER (ORDER BY [RS_NOM] DESC) AS RN 
    FROM DESTINATAIRE_TEMP 
) 
UPDATE DESTINATAIRE_TEMP SET CODE_DEST=RN 

लेकिन यह संघ के कारण भी काम नहीं करता है।

SQL Server 2008 R2 में ROW_NUMBER() फ़ंक्शन का उपयोग करके मैं कॉलम कैसे अपडेट कर सकता हूं?

+0

पोस्ट नमूना डेटा और अपेक्षित परिणाम, कि सबसे अच्छा तरीका है एक एसक्यूएल प्राप्त करने के लिए है के साथ जवाब अन्यथा आपका? इसका कोई मतलब नहीं है और इस तरह के उत्तर मिलेगा 'अद्यतन myCol = myCol + 1 MyTable से आईडी आईडी = @ MyID' – JonH

उत्तर

33
With UpdateData As 
(
SELECT RS_NOM, 
ROW_NUMBER() OVER (ORDER BY [RS_NOM] DESC) AS RN 
FROM DESTINATAIRE_TEMP 
) 
UPDATE DESTINATAIRE_TEMP SET CODE_DEST = RN 
FROM DESTINATAIRE_TEMP 
INNER JOIN UpdateData ON DESTINATAIRE_TEMP.RS_NOM = UpdateData.RS_NOM 
+1

यह केवल तभी काम करता है जब कॉलम RS_NOM में मान अद्वितीय हैं, है ना? मुझे संदेह है कि यह माना जा सकता है। – Toby

112

एक और विकल्प

UPDATE x 
SET x.CODE_DEST = x.New_CODE_DEST 
FROM (
     SELECT CODE_DEST, ROW_NUMBER() OVER (ORDER BY [RS_NOM]) AS New_CODE_DEST 
     FROM DESTINATAIRE_TEMP 
    ) x 
+0

उलझन में, आपके पास x नामक दो चर हैं। पहले var y का नाम बदलें और कृपया अपना उत्तर संपादित करें। – Craig

+14

@ क्रैग: "x नामक दो चर" से आपका क्या मतलब है? यह अद्यतन कथन किसी भी चर का संदर्भ नहीं दे रहा है। इस समाधान में * x * नाम की केवल एक चीज है और यह FROM खंड में परिभाषित व्युत्पन्न तालिका है। यहां कुछ भी संदिग्ध नहीं है। हो सकता है कि सिंटैक्स आपके लिए अपरिचित है, लेकिन यह ठीक है, आप बस इसके बारे में भ्रमित करने के बारे में बता सकते हैं और उम्मीद है कि आपके भ्रम को साफ़ करने के लिए प्रतिक्रिया प्राप्त करें (यदि मैनुअल मदद नहीं करता है)। –

+0

क्या यह एक शानदार उत्तर है, या यह शानदार है कि SQL सर्वर किसी नेस्टेड SELECT के भीतर अपडेट हो सकता है? मुझे लगता है कि दोनों हैं .... – Bigjim

10

क्योंकि आप CTE अंतर्निहित तालिका के रूप में एक ही नाम दिया है और CTE देखो जैसे कि यह एक पुनरावर्ती CTE था आपका दूसरा प्रयास मुख्य रूप से विफल रहा है, क्योंकि यह अनिवार्य रूप से खुद का संदर्भ दिया। recursive CTE में एक विशिष्ट संरचना होनी चाहिए जिसके लिए UNION ALL सेट ऑपरेटर के उपयोग की आवश्यकता हो।

बजाय, आप बस CTE एक अलग नाम यह करने के लिए दिया जा सकता था और साथ ही लक्ष्य स्तंभ जोड़ा के रूप में:

With SomeName As 
(
SELECT 
CODE_DEST, 
ROW_NUMBER() OVER (ORDER BY [RS_NOM] DESC) AS RN 
FROM DESTINATAIRE_TEMP 
) 
UPDATE SomeName SET CODE_DEST=RN 
0

सरल और आसान कर्सर अद्यतन करने के लिए जिस तरह से

UPDATE Cursor 
SET Cursor.CODE = Cursor.New_CODE 
FROM (
    SELECT CODE, ROW_NUMBER() OVER (ORDER BY [CODE]) AS New_CODE 
    FROM Table Where CODE BETWEEN 1000 AND 1999 
) Cursor 
40
DECLARE @id INT 
SET @id = 0 
UPDATE DESTINATAIRE_TEMP 
SET @id = CODE_DEST = @id + 1 
GO 

इस

http://www.mssqltips.com/sqlservertip/1467/populate-a-sql-server-column-with-a-sequential-number-not-using-an-identity/

+1

SQL सर्वर 2012 –

+3

में मेरे लिए काम करने वाले उपरोक्त में से केवल एक अच्छा जवाब! कोशिश करें: 'SET CODE_DEST = @id, @id = @id + 1' पठनीयता के लिए। –

6

यह @Aleksandr Fedorenko के जवाब का एक संशोधित संस्करण एक कहां खंड जोड़ रहा है:

UPDATE x 
SET x.CODE_DEST = x.New_CODE_DEST 
FROM (
     SELECT CODE_DEST, ROW_NUMBER() OVER (ORDER BY [RS_NOM]) AS New_CODE_DEST 
     FROM DESTINATAIRE_TEMP 
    ) x 
WHERE x.CODE_DEST <> x.New_CODE_DEST AND x.CODE_DEST IS NOT NULL 

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

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

यह भी सुनिश्चित करें कि आपके पास इंडेक्स हैं, खासकर अगर आपके पास SELECT कथन पर WHERE क्लॉज है। एक फ़िल्टर किए गए इंडेक्स ने मेरे लिए बहुत अच्छा काम किया क्योंकि मैं भुगतान की स्थिति के आधार पर फ़िल्टरिंग कर रहा था।


मेरे द्वारा

UPDATE UpdateTarget 
SET  PaidOrderIndex = New_PaidOrderIndex 
FROM 
(
    SELECT PaidOrderIndex, SimpleMembershipUserName, ROW_NUMBER() OVER(PARTITION BY SimpleMembershipUserName ORDER BY OrderId) AS New_PaidOrderIndex 
    FROM [Order] 
    WHERE PaymentStatusTypeId in (2,3,6) and SimpleMembershipUserName is not null 
) AS UpdateTarget 

WHERE UpdateTarget.PaidOrderIndex <> UpdateTarget.New_PaidOrderIndex AND UpdateTarget.PaidOrderIndex IS NOT NULL 

-- test to 'break' some of the rows, and then run the UPDATE again 
update [order] set PaidOrderIndex = 2 where PaidOrderIndex=3 

PARTITION का उपयोग कर क्वेरी हिस्सा अगर स्तंभ नल नहीं है 'शून्य नहीं है' की आवश्यकता नहीं है।


जब मैं कहता प्रदर्शन वृद्धि बड़े पैमाने पर मेरा मतलब यह अनिवार्य रूप से तात्कालिक था जब पंक्तियों की एक छोटी संख्या को अद्यतन करने गया था। सही अनुक्रमित के साथ मैं एक अद्यतन है कि 'आंतरिक' प्रश्न के रूप में उतना ही समय ले लिया अपने आप में करता है को प्राप्त करने में सक्षम था:

SELECT PaidOrderIndex, SimpleMembershipUserName, ROW_NUMBER() OVER(PARTITION BY SimpleMembershipUserName ORDER BY OrderId) AS New_PaidOrderIndex 
    FROM [Order] 
    WHERE PaymentStatusTypeId in (2,3,6) and SimpleMembershipUserName is not null 
+1

यह एक बहुत ही रोचक बिंदु है। धन्यवाद –

+0

@AleksandrFedorenko ईमानदार होने के लिए मुझे आश्चर्य हुआ कि यह काम किया लेकिन खुश हुआ :) :) इंडेक्स महत्वपूर्ण थे कि मैंने भी बनाया –

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