SQL सर्वर में JOIN का उपयोग कर एक टेबल को अपडेट करें?


834

मैं अन्य तालिका में शामिल होने वाली तालिका में एक कॉलम अपडेट करना चाहता हूं जैसे:

UPDATE table1 a 
INNER JOIN table2 b ON a.commonfield = b.[common field] 
SET a.CalculatedColumn= b.[Calculated Column]
WHERE 
    b.[common field]= a.commonfield
AND a.BatchNO = '110'

लेकिन यह शिकायत है:

Msg 170, स्तर 15, राज्य 1, पंक्ति 2
पंक्ति 2: 'a' के पास गलत सिंटैक्स।

यहाँ क्या गलत है?

जवाबों:


1596

आपके पास SQL ​​सर्वर का स्वामित्व UPDATE FROMसिंटैक्स नीचे नहीं है। यह भी सुनिश्चित नहीं करें कि आपको इसमें शामिल होने की आवश्यकता क्यों है CommonFieldऔर बाद में इस पर फ़िल्टर भी करें। इसे इस्तेमाल करे:

UPDATE t1
  SET t1.CalculatedColumn = t2.[Calculated Column]
  FROM dbo.Table1 AS t1
  INNER JOIN dbo.Table2 AS t2
  ON t1.CommonField = t2.[Common Field]
  WHERE t1.BatchNo = '110';

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

;WITH t2 AS
(
  SELECT [key], CalculatedColumn = SUM(some_column)
    FROM dbo.table2
    GROUP BY [key]
)
UPDATE t1
  SET t1.CalculatedColumn = t2.CalculatedColumn
  FROM dbo.table1 AS t1
  INNER JOIN t2
  ON t1.[key] = t2.[key];

यह वास्तव में मूर्खतापूर्ण है, यह है कि आप इस पूरे अपडेट को हर बार हर बार किसी भी table2परिवर्तन में फिर से चलाना चाहते हैं। ए SUMऐसी चीज है जिसे आप हमेशा रनटाइम पर गणना कर सकते हैं और ऐसा करने में, कभी भी चिंता करने की ज़रूरत नहीं है कि परिणाम बासी है।


3
जब मैं यह कोशिश करता हूं, तो यह पसंद नहीं है UPDATE table1 a SET a.[field] = b.[field] - एक उपनाम हटाने से काम होता है, इसलिएUPDATE table1 a SET [field] = b.[field]
बाल्डोमाशर

@baldmosher मैं शर्त लगाता हूं कि एक और मुद्दा है, क्या आप एसक्यूएल फिडेल पर एक रिप्रो पोस्ट कर सकते हैं?
एरोन बर्ट्रेंड

1
MySQL पर मेरे लिए काम नहीं किया। मुझे निम्नलिखित का उपयोग करना पड़ा (जो अधिक समझ में आता है) UPDATE t1 INNER JOIN t2 on t2.col = t1.col SET t1.field=value WHERE t2.col=something:।
जॉर्ज

15
@GeorgeRappel बेशक, कई अन्य प्लेटफार्मों पर भी काम नहीं करेगा। प्रश्न SQL सर्वर के बारे में है।
हारून बर्ट्रेंड

मान लीजिए कि t1 के कई रिकॉर्ड्स ने t2 से एक ही रिकॉर्ड को संदर्भित किया है, इसलिए कई पंक्तियों में दिए गए समान t2 रिकॉर्ड में शामिल होने के परिणाम हैं। अपने पहले उदाहरण में, यदि आप इसके बजाय t2 को अपडेट करते हैं, तो क्या यह कई बार या केवल एक बार रिकॉर्ड करेगा?
xr280xr

46

इसे इस तरह आज़माएं:

begin tran
    UPDATE a 
    SET a.CalculatedColumn= b.[Calculated Column]
    FROM table1 a INNER JOIN table2 b ON a.commonfield = b.[common field] 
    WHERE a.BatchNO = '110'
commit tran

29

हारून द्वारा दिया गया उत्तर सही है:

UPDATE a
  SET a.CalculatedColumn = b.[Calculated Column]
  FROM Table1 AS a
  INNER JOIN Table2 AS b
  ON a.CommonField = b.[Common Field]
  WHERE a.BatchNo = '110';

बस जोड़ना चाहते हैं कि SQL सर्वर में यह समस्या क्यों होती है जब हम उस तालिका को अद्यतन करते समय किसी अन्य तालिका का उपयोग करने का प्रयास करते हैं, नीचे उल्लेख वाक्यविन्यास हमेशा त्रुटि देगा:

update tableName t 
set t.name = 'books new' 
where t.id = 1

यदि आप किसी एकल तालिका को अपडेट कर रहे हैं या जुड़ने के दौरान अपडेट कर रहे हैं तो मामला कोई भी हो सकता है।

यद्यपि उपरोक्त क्वेरी PL / SQL में ठीक काम करेगी लेकिन SQL सर्वर में नहीं।

SQL सर्वर में तालिका उपनाम का उपयोग करते हुए तालिका को अपडेट करने का सही तरीका है:

update t 
set t.name = 'books new' 
from tableName t 
where t.id = 1

आशा है कि यह सभी को मदद करेगा कि यहाँ त्रुटि क्यों आई।


अच्छा आपका धन्यवाद। इस प्रश्न के लिए आपका उत्तर सही है।
ओला स्ट्रोम

4
MERGE table1 T
   USING table2 S
      ON T.CommonField = S."Common Field"
         AND T.BatchNo = '110'
WHEN MATCHED THEN
   UPDATE
      SET CalculatedColumn = S."Calculated Column";

3

SQL सर्वर 2012 की तरह लगता है Teradata के पुराने अद्यतन वाक्यविन्यास भी संभाल सकते हैं:

UPDATE a
SET a.CalculatedColumn= b.[Calculated Column]
FROM table1 a, table2 b 
WHERE 
    b.[common field]= a.commonfield
AND a.BatchNO = '110'

अगर मुझे सही से याद है, तो 2008R2 मैं इसी तरह की क्वेरी की कोशिश करते समय त्रुटि दे रहा था।



2

मैं अद्यतन करने से पहले परीक्षण के रूप में उन पंक्तियों को प्राप्त करने के लिए एक अपडेट में एक अद्यतन को चालू करना उपयोगी समझता हूं। यदि मैं अपनी इच्छित पंक्तियों का चयन कर सकता हूं, तो मैं केवल उन पंक्तियों को अपडेट कर सकता हूं जिन्हें मैं अद्यतन करना चाहता हूं।

DECLARE @expense_report_id AS INT
SET @expense_report_id = 1027

--UPDATE expense_report_detail_distribution
--SET service_bill_id = 9

SELECT *
FROM expense_report_detail_distribution erdd
INNER JOIN expense_report_detail erd
INNER JOIN expense_report er 
    ON er.expense_report_id = erd.expense_report_id 
    ON erdd.expense_report_detail_id = erd.expense_report_detail_id
WHERE er.expense_report_id = @expense_report_id

2
    UPDATE mytable
         SET myfield = CASE other_field
             WHEN 1 THEN 'value'
             WHEN 2 THEN 'value'
             WHEN 3 THEN 'value'
         END
    From mytable
    Join otherTable on otherTable.id = mytable.id
    Where othertable.somecolumn = '1234'

अधिक विकल्प यहाँ


0

एक और दृष्टिकोण होगा MERGE का उपयोग करना

  ;WITH cteTable1(CalculatedColumn, CommonField)
  AS
  (
    select CalculatedColumn, CommonField from Table1 Where BatchNo = '110'
  )
  MERGE cteTable1 AS target
    USING (select "Calculated Column", "Common Field" FROM dbo.Table2) AS source ("Calculated Column", "Common Field")
    ON (target.CommonField = source."Common Field")
    WHEN MATCHED THEN 
        UPDATE SET target.CalculatedColumn = source."Calculated Column";

-मेजर SQL स्टैंडर्ड का हिस्सा है

-क्योंकि मुझे पूरा यकीन है कि इनर जुड़ने वाले अपडेट नॉन निर्धारक होते हैं .. यहाँ भी इसी तरह का सवाल है जिसके बारे में जवाब में बात की जाती है कि http://ask.sqlservercentral.com/questions/19089/updating-two-tables-use-single-query। एचटीएमएल


3
हालांकि वे मानक हो सकते हैं, मैं बहुत सावधान रहना होगाMERGE
हारून बर्ट्रेंड

1
जो हर तरह से मज़ेदार है क्योंकि शाब्दिक रूप से 5 मिनट के बाद मैंने इसे पोस्ट किया है जो मुझे विरासत में मिले कुछ समस्याग्रस्त गैर-नियतात्मक अद्यतनों पर हुआ है :-) मजेदार सामान
शेन नेविल

यह मर्ज को बेहतर नहीं बनाता है, इसका मतलब है कि आपके पास खराब अपडेट हैं।
आरोन बर्ट्रेंड

1
हाँ, मैं सिर्फ किस्सागोई कर रहा था :-) मेरे दिमाग में यह था जब मैंने वापस स्प्रो में गोता लगाया और यह पहली चीज थी जिसे मैंने देखा था।
शेन न्युविले

2
सीटीई मानक हैं; वर्ग कोष्ठक मूर्खतापूर्ण नामों से बचने के लिए (दोहरे उद्धरण चिह्नों) नहीं हैं।
onedaywhen

0

मेरे पास एक ही मुद्दा था .. और आपको एक भौतिक कॉलम जोड़ने की आवश्यकता नहीं है .. cuz अब आपको इसे बनाए रखना होगा .. जो आप कर सकते हैं वह चुनिंदा क्वेरी में एक जेनेरिक कॉलम जोड़ सकता है:

पूर्व:

select tb1.col1, tb1.col2, tb1.col3 ,
( 
select 'Match' from table2 as tbl2
where tbl1.col1 = tbl2.col1 and tab1.col2 = tbl2.col2
)  
from myTable as tbl1

0

आरोन के ऊपर के दृष्टिकोण ने मेरे लिए पूरी तरह से काम किया। मेरा अपडेट स्टेटमेंट थोड़ा अलग था, क्योंकि मुझे एक टेबल में दूसरे फील्ड में मैच करने के लिए एक टेबल में दो फील्ड के आधार पर जुड़ने की जरूरत थी।

 --update clients table cell field from custom table containing mobile numbers

update clients
set cell = m.Phone
from clients as c
inner join [dbo].[COSStaffMobileNumbers] as m 
on c.Last_Name + c.First_Name = m.Name

-3

प्रयत्न:

UPDATE table1
SET CalculatedColumn = ( SELECT [Calculated Column] 
                         FROM table2 
                         WHERE table1.commonfield = [common field])
WHERE  BatchNO = '110'

6
मैं नीच कर रहा हूं, क्योंकि यह हर पंक्ति को अपडेट करेगा table1, न केवल उन पंक्तियों में जहां दोनों तालिकाओं के बीच आम क्षेत्र पर एक मैच है (प्रभावी रूप से एक बाईं ओर और एक आंतरिक जुड़ाव नहीं)।
C

@ C @: आपका मतलब है कि यह हर पंक्ति के मिलान को अद्यतन करेगा BatchNo = '110', है ना? क्या सभी डाउनवोट इस प्रभाव के परिणामस्वरूप आए थे, या दूसरों के पास डाउन-वोटिंग के अन्य कारण थे?
पलसीम

मैं पूछता हूं क्योंकि कुछ स्वीकार कर सकते हैं कि UPDATE ऑपरेशन कुछ पंक्तियों को सेट कर सकता है NULL, और यह फ़ॉर्म कम T-SQL विशिष्ट समाधान हो सकता है।
पलसीम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.