MySQL - UPDATE query based on SELECT Query

Viewed 1335606

I need to check (from the same table) if there is an association between two events based on date-time.

One set of data will contain the ending date-time of certain events and the other set of data will contain the starting date-time for other events.

If the first event completes before the second event then I would like to link them up.

What I have so far is:

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

Then I join them:

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

Can I then, based on my validation_check field, run a UPDATE query with the SELECT nested?

13 Answers

You can actually do this one of two ways:

MySQL update join syntax:

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 syntax:

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)

Pick whichever one seems most natural to you.

I had an issue with duplicate entries in one table itself. Below is the approaches were working for me. It has also been advocated by @sibaz.

Finally I solved it using the below queries:

  1. The select query is saved in a temp table

    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. The temp table is joined in the update query.

    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
    )
    

I not very experienced with SQL please advise any better approach you know.

Above queries are for MySql server.

if you are updating from a complex query. The best thing is create temporary table from the query, then use the temporary table to update as one query.

    DROP TABLE IF EXISTS cash_sales_sums;
CREATE TEMPORARY TABLE cash_sales_sums as
SELECT tbl_cash_sales_documents.batch_key, COUNT(DISTINCT tbl_cash_sales_documents.cash_sale_number) no_of_docs,
  SUM(tbl_cash_sales_documents.paid_amount) paid_amount, SUM(A.amount - tbl_cash_sales_documents.bonus_amount - tbl_cash_sales_documents.discount_given) amount,
  SUM(A.recs) no_of_entries FROM 
        tbl_cash_sales_documents
    RIGHT JOIN(
        SELECT
            SUM(
                tbl_cash_sales_transactions.amount
            )amount,
            tbl_cash_sales_transactions.cash_sale_document_id,
            COUNT(transaction_id)recs
        FROM
            tbl_cash_sales_transactions
        GROUP BY
            tbl_cash_sales_transactions.cash_sale_document_id
    )A ON A.cash_sale_document_id = tbl_cash_sales_documents.cash_sale_id
    GROUP BY
        tbl_cash_sales_documents.batch_key
ORDER BY batch_key;





UPDATE tbl_cash_sales_batches SET control_totals = (SELECT amount FROM cash_sales_sums WHERE cash_sales_sums.batch_key = tbl_cash_sales_batches.batch_key LIMIT 1),
expected_number_of_documents = (SELECT no_of_docs FROM cash_sales_sums WHERE cash_sales_sums.batch_key = tbl_cash_sales_batches.batch_key),
computer_number_of_documents = expected_number_of_documents,  computer_total_amount = control_totals
WHERE batch_key IN (SELECT batch_key FROM cash_sales_sums);
INSERT INTO all_table
SELECT Orders.OrderID,
    Orders.CustomerID,
    Orders.Amount,
    Orders.ProductID,
    Orders.Date,
    Customer.CustomerName,
    Customer.Address
FROM Orders
JOIN Customer ON Orders.CustomerID=Customer.CustomerID
WHERE Orders.OrderID not in (SELECT OrderID FROM all_table)
Related