MySQL - चयनित क्वेरी के आधार पर अद्यतन क्वेरी


501

अगर तारीख-समय के आधार पर दो घटनाओं के बीच संबंध है, तो मुझे (उसी तालिका से) जांच करने की आवश्यकता है।

डेटा के एक सेट में कुछ घटनाओं की समाप्ति तिथि-समय होगा और डेटा के दूसरे सेट में अन्य घटनाओं के लिए प्रारंभिक तिथि-समय होगा।

अगर पहली घटना दूसरी घटना से पहले पूरी हो जाती है तो मैं उन्हें जोड़ना चाहूंगा।

मेरे पास अब तक क्या है:

SELECT name as name_A, date-time as end_DTS, id as id_A 
FROM tableA WHERE criteria = 1


SELECT name as name_B, date-time as start_DTS, id as id_B 
FROM tableA WHERE criteria = 2

फिर मैं उनके साथ शामिल हो गया:

SELECT name_A, name_B, id_A, id_B, 
if(start_DTS > end_DTS,'VALID','') as validation_check
FROM tableA
LEFT JOIN tableB ON name_A = name_B

क्या तब मैं अपने सत्यापन_चेक क्षेत्र के आधार पर चयन नस्टेड के साथ अद्यतन क्वेरी चला सकता हूं?


2
मुझे यकीन नहीं है कि आप क्या पूछ रहे हैं? क्या आप यह पता लगाने की कोशिश कर रहे हैं कि SQL चयन के साथ अपडेट कैसे किया जाए?
रिडलरडेव

जवाबों:


811

आप वास्तव में दो तरीकों में से एक कर सकते हैं:

MySQL अपडेट सिंटैक्स में शामिल होता है:

UPDATE tableA a
INNER JOIN tableB b ON a.name_a = b.name_b
SET validation_check = if(start_dts > end_dts, 'VALID', '')
-- where clause can go here

ANSI SQL सिंटैक्स:

UPDATE tableA SET validation_check = 
    (SELECT if(start_DTS > end_DTS, 'VALID', '') AS validation_check
        FROM tableA
        INNER JOIN tableB ON name_A = name_B
        WHERE id_A = tableA.id_A)

जो कोई भी आपको सबसे अधिक स्वाभाविक लगता है उसे चुनें।


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

16
पहले उदाहरण के लिए, क्या आपको एक आंतरिक जुड़ाव का उपयोग नहीं करना चाहिए? मान्य तालिका में बचे हुए जॉइन रिजल्ट को टेबल टेबल रिकॉर्ड के बिना शून्य करने के लिए सेट नहीं किया जाएगा?
सेरिन

3
@ मेरी बात जो मेरे साथ हुई। यह आंतरिक जुड़ाव होना चाहिए! या सिर्फ जुड़ने पर छोड़ दें। यदि आपके पास इनर जॉइन नहीं है, तो लेफ्ट जॉइन का मतलब है कि सभी टेबलए रिकॉर्ड अपडेट हो जाएंगे! यह बहुत खतरनाक है!
CMCDragonkai

10
पहले (y) के लिए धन्यवाद। जबकि यह उत्तर 7 साल से अधिक पुराना है। मैं विश्वास नहीं कर सकता कि क्यों किसी ने कहा है कि दूसरा MySQL जैसे कुछ डेटाबेस में काम नहीं करता है। आपको यह त्रुटि You can't specify target table ___ for update in FROM clause SQL.sql
मिलेगी

1
यह भी ध्यान दें कि हाल ही में, जब तक MySQL के साथ पहला दृष्टिकोण काम नहीं करता है tableA= tableB। आपको मध्यवर्ती परिणाम संग्रहीत करने के लिए एक अस्थायी तालिका बनाने के लिए मजबूर किया जाता है। (माइग्रेशन स्क्रिप्ट के लिए एक समान क्वेरी
लिखनी

301
UPDATE
    `table1` AS `dest`,
    (
        SELECT
            *
        FROM
            `table2`
        WHERE
            `id` = x
    ) AS `src`
SET
    `dest`.`col1` = `src`.`col1`
WHERE
    `dest`.`id` = x
;

उम्मीद है इससे आपका काम बनेगा।


5
यह अब तक की सबसे तेज क्वेरी है। संपादित करें: 22K पंक्तियों के साथ भाग्य, और 4K पंक्तियों के साथ src, यह 1 सेकंड के तहत पूरा करने के लिए ले लिया, जबकि 60 सेकंड में शीर्ष उत्तर।
क्रिस देव

1
हां, यह सबसे तेज क्वेरी है, BTW आप WHERE क्लॉज भी जोड़ सकते हैं
robinmag

1
सबसे तेजी से हमेशा अच्छा नहीं होता है, यह अपडेट सभी मामलों में काम नहीं करेगा, वास्तव में कुछ मामलों में आपके साथ अप्रत्याशित व्यवहार होगा, यह सब इसीलिए एक शर्त नहीं है और वह इसमें शामिल नहीं है
एमिलियानो


58

यदि कोई व्यक्ति किसी डेटाबेस से डेटा को किसी अन्य तालिका के लिए अद्यतन करना चाह रहा है, तो वह कोई भी तालिका है, तो उसे करने के लिए कुछ मापदंड होने चाहिए।

यह सभी स्तरों के लिए बेहतर और साफ है:

UPDATE dbname1.content targetTable

LEFT JOIN dbname2.someothertable sourceTable ON
    targetTable.compare_field= sourceTable.compare_field
SET
    targetTable.col1  = sourceTable.cola,
    targetTable.col2 = sourceTable.colb, 
    targetTable.col3 = sourceTable.colc, 
    targetTable.col4 = sourceTable.cold 

Traaa! यह बहुत अच्छा काम करता है!

उपरोक्त समझ के साथ, आप अपना कार्य करने के लिए निर्धारित फ़ील्ड और "ऑन" मापदंड को संशोधित कर सकते हैं। आप चेक भी कर सकते हैं, फिर डेटा को टेम्प टेबल (एस) में खींच सकते हैं और फिर अपने टेबल और कॉलम नामों की जगह उपरोक्त सिंटैक्स का उपयोग करके अपडेट चला सकते हैं।

आशा है कि यह काम करता है, अगर मुझे पता नहीं है। मैं आपके लिए एक सटीक क्वेरी लिखूंगा।


24
UPDATE 
  receipt_invoices dest,
  (
    SELECT 
      `receipt_id`,
      CAST((net * 100) / 112 AS DECIMAL (11, 2)) witoutvat 
    FROM
      receipt 
    WHERE CAST((net * 100) / 112 AS DECIMAL (11, 2)) != total 
      AND vat_percentage = 12
  ) src 
SET
  dest.price = src.witoutvat,
  dest.amount = src.witoutvat 
WHERE col_tobefixed = 1 
  AND dest.`receipt_id` = src.receipt_id ;

आशा है कि यह आपको एक ऐसे मामले में मदद करेगा जहाँ आपको दो तालिकाओं के बीच मिलान और अद्यतन करना होगा।


12

मुझे यह सवाल बहुत जटिल जुड़ाव के अपने समाधान की तलाश में मिला। यह समस्या के अधिक जटिल संस्करण के लिए एक वैकल्पिक समाधान है, जो मुझे लगा कि उपयोगी हो सकता है।

मुझे गतिविधियों की तालिका में product_id फ़ील्ड को पॉप्युलेट करने की आवश्यकता है, जहां गतिविधियों को एक इकाई में गिना जाता है, और इकाइयों को एक स्तर (एक स्ट्रिंग ?? एन का उपयोग करके पहचाना जाता है) में क्रमांकित किया जाता है, जैसे कि एक SKU अर्थात L1U1.11 का उपयोग करके गतिविधियों की पहचान कर सकते हैं। उन SKU को तब एक अलग तालिका में संग्रहीत किया जाता है।

मैंने गतिविधि की सूची प्राप्त करने के लिए निम्नलिखित की पहचान की है।

SELECT a.activity_id, w.product_id 
  FROM activities a 
  JOIN units USING(unit_id) 
  JOIN product_types USING(product_type_id) 
  JOIN web_products w 
    ON sku=CONCAT('L',SUBSTR(product_type_code,3), 'U',unit_index, 'A',activity_index)

मैंने पाया कि mysql में एक SELECT में शामिल होना बहुत जटिल था, इसलिए मैंने एक अस्थायी तालिका बनाई, और अपडेट स्टेटमेंट में शामिल हो गया: -

CREATE TEMPORARY TABLE activity_product_ids AS (<the above select statement>);

UPDATE activities a
  JOIN activity_product_ids b
    ON a.activity_id=b.activity_id 
  SET a.product_id=b.product_id;

मुझे आशा है कि किसी को यह उपयोगी लगता है


दो क्वेरी बहु थ्रेडेड वातावरण में लगातार परिणाम नहीं दे सकते हैं।
डॉनल्ड

7
UPDATE [table_name] AS T1,
      (SELECT [column_name] 
        FROM [table_name] 
        WHERE [column_name] = [value]) AS T2 
  SET T1.[column_name]=T2.[column_name] + 1
WHERE T1.[column_name] = [value];

4

आप इस तरह से आंतरिक जुड़ाव का उपयोग करके किसी अन्य तालिका से मान अपडेट कर सकते हैं

UPDATE [table1_name] AS t1 INNER JOIN [table2_name] AS t2 ON t1.column1_name] = t2.[column1_name] SET t1.[column2_name] = t2.column2_name];

इस क्वेरी का उपयोग करने का तरीका जानने के लिए यहां क्लिक करें http://www.voidtricks.com/mysql-inner-join-update/

या आप ऐसा करने के लिए चुनिंदा उपकुंजी के रूप में उपयोग कर सकते हैं

UPDATE [table_name] SET [column_name] = (SELECT [column_name] FROM [table_name] WHERE [column_name] = [value]) WHERE [column_name] = [value];

क्वेरी यहाँ विवरण में समझाया http://www.voidtricks.com/mysql-update-from-select/


4

आप उपयोग कर सकते हैं:

UPDATE Station AS st1, StationOld AS st2
   SET st1.already_used = 1
 WHERE st1.code = st2.code

3

उसी तालिका के लिए,

UPDATE PHA_BILL_SEGMENT AS PHA,
     (SELECT BILL_ID, COUNT(REGISTRATION_NUMBER) AS REG 
       FROM PHA_BILL_SEGMENT
        GROUP BY REGISTRATION_NUMBER, BILL_DATE, BILL_AMOUNT
        HAVING REG > 1) T
    SET PHA.BILL_DATE = PHA.BILL_DATE + 2
 WHERE PHA.BILL_ID = T.BILL_ID;

1

मेरे पास एक तालिका में डुप्लिकेट प्रविष्टियों के साथ एक समस्या थी। नीचे दृष्टिकोण मेरे लिए काम कर रहे थे। इसकी वकालत @sibaz ने भी की है।

अंत में मैंने इसे नीचे दिए गए प्रश्नों का उपयोग करके हल किया:

  1. एक अस्थायी तालिका में चयनित क्वेरी को सहेजा जाता है

    IF OBJECT_ID(N'tempdb..#New_format_donor_temp', N'U') IS NOT NULL
        DROP TABLE #New_format_donor_temp;
    
    select *
    into #New_format_donor_temp
    from DONOR_EMPLOYMENTS
    where DONOR_ID IN (
      1, 2
    )
    
    -- Test New_format_donor_temp
    -- SELECT *
    -- FROM #New_format_donor_temp;
  2. अस्थायी तालिका अद्यतन क्वेरी में शामिल हो गई है।

    UPDATE de
    SET STATUS_CD=de_new.STATUS_CD, STATUS_REASON_CD=de_new.STATUS_REASON_CD, TYPE_CD=de_new.TYPE_CD
    FROM DONOR_EMPLOYMENTS AS de
      INNER JOIN #New_format_donor_temp AS de_new ON de_new.EMP_NO = de.EMP_NO
    WHERE
      de.DONOR_ID IN (
        3, 4
    )

मैं SQL के साथ बहुत अनुभवी नहीं हूँ कृपया किसी भी बेहतर दृष्टिकोण की सलाह दें जो आप जानते हैं।

उपरोक्त प्रश्न MySql सर्वर के लिए हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.