मैं SQL सर्वर में JOIN के साथ एक अद्यतन कैसे कर सकता हूँ?


1314

मुझे अपनी 'पैरेंट' टेबल के डेटा के साथ SQL सर्वर में इस तालिका को अपडेट करने की आवश्यकता है , नीचे देखें:

तालिका: बिक्री

id (int)
udid (int)
assid (int)

टेबल: ud

id  (int)
assid  (int)

sale.assidअद्यतन करने के लिए सही मान है ud.assid

यह कौन सी क्वेरी करेगा? मैं सोच रहा हूँ, joinलेकिन मुझे यकीन नहीं है कि यह संभव है।


3
आप RDBMS क्या उपयोग कर रहे हैं? MySQL, SQL Server, Oracle, PostgreSQL या कुछ और?
क्रिस जे

तालिकाओं के बीच कुछ संबंध? कोई यह कैसे जान सकता है कि बिक्री से कौन सा रिकॉर्ड ud से किस रिकॉर्ड से मेल खाता है? क्या यह दोनों तालिकाओं में प्राथमिक कुंजी के रूप में आईडी पर आधारित है?
Cătălin Pitiș

आप UD को कैसे अपडेट कर सकते हैं? इसमें केवल एसिड है और यह स्वयं की आईडी है। क्या आप वास्तविक मूल्यों के संदर्भ में एक उदाहरण दे सकते हैं, और स्क्रिप्ट के परिणामस्वरूप आप जो रिकॉर्ड बदलना या जोड़ना चाहते हैं?
बर्नहार्ड हॉफमैन

2
एसओ प्रश्न भी देखें ... stackoverflow.com/questions/982919/sql-update-query-use-joins
स्टीवसी

2
जैसी क्वेरी में उपयोगकर्ता का प्रचलित नाम stackoverflow.com/questions/982919/sql-update-query-using-joins
इमरान मुहम्मद

जवाबों:


2383

सिंटैक्स सख्ती से निर्भर करता है कि आप किस SQL ​​DBMS का उपयोग कर रहे हैं। एएनएसआई / आईएसओ (किसी भी SQL DBMS पर काम करना चाहिए), MySQL, SQL सर्वर और Oracle में इसे करने के कुछ तरीके यहां दिए गए हैं। यह सलाह दी जाती है कि मेरी सुझाई गई ANSI / ISO विधि आम तौर पर अन्य दो तरीकों की तुलना में बहुत धीमी होगी, लेकिन यदि आप MySQL, SQL सर्वर या Oracle के अलावा किसी SQL DBMS का उपयोग कर रहे हैं, तो यह जाने का एकमात्र तरीका हो सकता है (जैसे यदि आपका SQL DBMS समर्थन नहीं करता है MERGE):

एएनएसआई / आईएसओ:

update ud 
     set assid = (
          select sale.assid 
          from sale 
          where sale.udid = ud.id
     )
 where exists (
      select * 
      from sale 
      where sale.udid = ud.id
 );

माई एसक्यूएल:

update ud u
inner join sale s on
    u.id = s.udid
set u.assid = s.assid

एस क्यू एल सर्वर:

update u
set u.assid = s.assid
from ud u
    inner join sale s on
        u.id = s.udid

PostgreSQL:

update ud
  set assid = s.assid
from sale s 
where ud.id = s.udid;

ध्यान दें कि FROMपोस्टग्रेज के लिए लक्ष्य तालिका को खंड में दोहराया नहीं जाना चाहिए ।

आकाशवाणी:

update
    (select
        u.assid as new_assid,
        s.assid as old_assid
    from ud u
        inner join sale s on
            u.id = s.udid) up
set up.new_assid = up.old_assid

SQLite:

update ud 
     set assid = (
          select sale.assid 
          from sale 
          where sale.udid = ud.id
     )
 where RowID in (
      select RowID 
      from ud 
      where sale.udid = ud.id
 );

3
यह मुझे लगता है कि MySQL set assid = s.assidहोना चाहिए set u.assid = s.assid
dotancohen

2
ANSI सिंटैक्स में, =एक पंक्ति से अधिक रिटर्न के बाद SELECT होने पर क्या होता है ?
दूर फेंक दें

2
@ ThrowawayAccount3Million यह शायद विफल होगा। AFAIK, इस तरह के ऑपरेशन से एक स्केलर मूल्य की उम्मीद होगी और यदि परिणाम के बजाय सेट किया गया है तो एक त्रुटि होगी।
फ्रांसिस लॉर्ड

6
काश ओपी अपनी मेज और कॉलम के लिए कुछ बेहतर नामों का चयन करता !! यह इतना पठनीय / सहज ज्ञान युक्त नहीं है ...
S.Serpooshan

4
Postgre 9.3 केवल का उपयोग कर काम कियाupdate ud set assid = s.assid
StackUnder

143

यह SQL सर्वर में काम करना चाहिए:

update ud 
set assid = sale.assid
from sale
where sale.udid = id

98

postgres

UPDATE table1
SET    COLUMN = value
FROM   table2,
       table3
WHERE  table1.column_id = table2.id
       AND table1.column_id = table3.id
       AND table1.COLUMN = value
       AND table2.COLUMN = value
       AND table3.COLUMN = value 

20
यदि यह प्रश्न में प्रयुक्त तालिका / स्तंभ नामों का उपयोग करेगा तो उत्तर अधिक उपयोगी होगा। आपके जवाब में 3 टेबल क्यों हैं?
अल्फोंक्स

50

एक मानक SQL दृष्टिकोण होगा

UPDATE ud
SET assid = (SELECT assid FROM sale s WHERE ud.id=s.id)

SQL Server पर आप एक join का उपयोग कर सकते हैं

UPDATE ud
SET assid = s.assid
FROM ud u
JOIN sale s ON u.id=s.id

1
पहले एक के साथ, आप 2+ कॉलम पर मेल नहीं कर सकते हैं, लेकिन शानदार काम करते हैं।
मैक

6
@makciook: हुह? WHEREयदि आप अतिरिक्त स्तंभों पर मिलान करना चाहते हैं तो आप क्लॉज़ में अधिक शर्तें जोड़ सकते हैं।
siride

2
बस एक नाइट ... लेकिन मुझे लगता है कि ओपी का मतलब बिक्री था। और बिक्री नहीं।
स्किप्पी वॉनड्रैक

39

PostgreSQL :

CREATE TABLE ud (id integer, assid integer);
CREATE TABLE sales (id integer, udid integer, assid integer);

UPDATE ud
SET assid = sales.assid
FROM sales
WHERE sales.id = ud.id;

26

JOIN -ing कई तालिकाओं का उपयोग करके सरलीकृत अद्यतन क्वेरी ।

   UPDATE
        first_table ft
        JOIN second_table st ON st.some_id = ft.some_id
        JOIN third_table tt  ON tt.some_id = st.some_id
        .....
    SET
        ft.some_column = some_value
    WHERE ft.some_column = 123456 AND st.some_column = 123456

नोट - first_table, second_table, third_table और some_column जैसे 123456 डेमो टेबल नेम, कॉलम नेम और आईडी हैं। उन्हें मान्य नामों से बदलें।


16

एक और उदाहरण कि SQL वास्तव में पोर्टेबल क्यों नहीं है।

MySQL के लिए यह होगा:

update ud, sale
set ud.assid = sale.assid
where sale.udid = ud.id;

अधिक जानकारी के लिए कई टेबल अपडेट पढ़ें: http://dev.mysql.com/doc/refman/5.0/en/updateate.html

UPDATE [LOW_PRIORITY] [IGNORE] table_references
    SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ...
    [WHERE where_condition]

2
+1 "एसक्यूएल वास्तव में पोर्टेबल क्यों नहीं है" टिप्पणी पर! पोर्टेबिलिटी इतनी नाजुक है कि सिर्फ एक वेरिएबल की घोषणा करने से कई लोकप्रिय डेटाबेस इंजनों के बीच पोर्टेबिलिटी टूट जाएगी।
जेफ मोदन

8

Teradata Aster लक्ष्य प्राप्त करने का एक और दिलचस्प तरीका प्रदान करता है:

MERGE INTO ud --what trable should be updated
USING sale -- from what table/relation update info should be taken
ON ud.id = sale.udid --join condition
WHEN MATCHED THEN 
    UPDATE SET ud.assid = sale.assid; -- how to update

8

मैं सोच रहा था कि शीर्ष पद पर SQL- सर्वर एक Sybase के लिए काम करेगा क्योंकि वे दोनों टी-SQL हैं, लेकिन दुर्भाग्य से नहीं।

Sybase के लिए मुझे पता चला कि अद्यतन तालिका में ही नहीं होना चाहिए:

update ud
set u.assid = s.assid
from ud u
    inner join sale s on
        u.id = s.udid

7

FROM कीवर्ड के साथ निम्न कथन का उपयोग एक पंक्ति के साथ कई पंक्तियों को अद्यतन करने के लिए किया जाता है

UPDATE users 
set users.DivisionId=divisions.DivisionId
from divisions join users on divisions.Name=users.Division

7

माई एसक्यूएल

यदि आप क्लॉज़ को भूल जाते हैं और सभी स्थितियों को ऑन एक्सप्रेशन में रखते हैं तो आपको सबसे अच्छा प्रदर्शन मिलेगा।

मुझे लगता है कि यह इसलिए है क्योंकि क्वेरी को पहले तालिकाओं में शामिल करना होता है, फिर उस पर क्लॉज़ को चलाता है, इसलिए यदि आप इसमें शामिल होने के लिए आवश्यक चीज़ों को कम कर सकते हैं तो परिणाम प्राप्त करने के लिए तेज़ तरीका है और udpate करें।

उदाहरण

परिदृश्य

आपके पास उपयोगकर्ताओं की एक तालिका है। वे अपने उपयोगकर्ता नाम या ईमेल या account_number का उपयोग करके लॉग इन कर सकते हैं। ये खाते सक्रिय (1) या निष्क्रिय (0) हो सकते हैं। इस तालिका में 50000 पंक्तियाँ हैं

फिर आपके पास एक बार में अक्षम करने के लिए उपयोगकर्ताओं की एक तालिका होती है क्योंकि आपको पता चलता है कि वे सभी कुछ खराब कर चुके हैं। इस तालिका में, उपयोगकर्ता नाम, ईमेल और खाता संख्याओं के साथ एक कॉलम है। इसमें एक "has_run" संकेतक भी है जिसे चलाने पर इसे 1 (सही) पर सेट करने की आवश्यकता होती है

सवाल

UPDATE users User
    INNER JOIN
        blacklist_users BlacklistUser
        ON
        (
            User.username = BlacklistUser.account_ref
            OR
            User.email = BlacklistedUser.account_ref
            OR
            User.phone_number = BlacklistUser.account_ref
            AND
            User.is_active = 1
            AND
            BlacklistUser.has_run = 0
        )
    SET
        User.is_active = 0,
        BlacklistUser.has_run = 1;

विचार

अगर हमें सिर्फ OR शर्तों पर शामिल होना था तो अनिवार्य रूप से प्रत्येक पंक्ति को 4 बार जांचना होगा कि क्या उसे शामिल होना चाहिए या नहीं, और संभवतः बहुत अधिक पंक्तियों को वापस करना होगा। हालाँकि, इसे और अधिक शर्तें देकर यह बहुत सी पंक्तियों को "छोड़" सकता है यदि वे शामिल होने पर सभी शर्तों को पूरा नहीं करते हैं।

बक्शीश

यह अधिक पठनीय है। सभी स्थितियाँ एक स्थान पर हैं और अद्यतन करने के लिए पंक्तियाँ एक ही स्थान पर हैं


4

और MS ACCESS में:

UPDATE ud 
INNER JOIN sale ON ud.id = sale.udid
SET ud.assid = sale.assid;

1
सावधानी के रूप में, SET को रिकॉर्डसेट की परिभाषा के तुरंत बाद आना चाहिए! मैं सिर्फ एक एक्सेस डेटाबेस में एक समान परिदृश्य पर काम करने की कोशिश कर रहा हूं, जिसे WHERE क्लॉज की आवश्यकता थी (इसे मान्य ओएन कंडीशन के रूप में स्वीकार नहीं किया जाएगा)। वाक्यविन्यास त्रुटियों से बचने के लिए अंतिम रूप से कहां आना था।
डोडेकाफोन



3

यह एक कोशिश करो, मुझे लगता है कि यह आपके लिए काम करेगा

update ud

set ud.assid = sale.assid

from ud 

Inner join sale on ud.id = sale.udid

where sale.udid is not null

2

SQLite के लिए अद्यतन करने के लिए पंक्ति संपत्ति का उपयोग करें:

update Table set column = 'NewValue'
where RowID = 
(select t1.RowID from Table t1
join Table2 t2 on t1.JoinField = t2.JoinField
where t2.SelectValue = 'FooMyBarPlease');

1
क्या आप इसे थोड़ा समझा सकते हैं?
मोहम्मद नौरेलिन

1
@MohammedNoureldin मैं समझाने की कोशिश करूँगा। समस्या यह है कि उसी तालिका का उपयोग करके सम्मिलित पर क्वेरी से परिणाम तालिका को कैसे अपडेट किया जाए। (सब-सिलेक्ट) स्टेटमेंट एक जॉइन की तरह काम करता है और एक सिस्टम फील्ड, रोविड लौटाता है, जो एक टेबल में प्रत्येक पंक्ति के लिए एक अद्वितीय संख्या है। चूंकि उप-चयन कई पंक्तियों को "जहां पंक्ति =" वापस कर सकता है, परिणामस्वरूप उप-चयन में से एक एकल सही पंक्ति का चयन करता है और कॉलम को अपडेट करता है। मुझे पता है कि क्या आप और अधिक स्पष्टीकरण की जरूरत है या इस विषय पर एक बदलाव का पता लगाने की जरूरत है।
कीथTheBiped
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.