MySQL-SELECT 쿼리 기반 업데이트 쿼리


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

그런 다음 validation_check 필드를 기반으로 SELECT 중첩 된 UPDATE 쿼리를 실행할 수 있습니까?


2
나는 당신이 무엇을 요구하는지 잘 모르겠습니다. SQL Select로 업데이트하는 방법을 알아 내려고 노력하고 있습니까?
RiddlerDev

답변:


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
첫 번째 형태 (가입과 갱신)이 될 것입니다 많은 두 번째보다 더 효율적입니다. 첫 번째는 단일 조인을 수행하는 반면 두 번째는 tableA의 모든 행에 대해 select 쿼리를 실행합니다.
ColinM

16
첫 번째 예에서는 내부 조인을 사용하지 않아야합니까? 해당 tableB 레코드가없는 tableA 레코드에 대해 validation_check가 왼쪽 결합 결과로 null로 설정되지 않습니까?
Cerin

3
@Cerin 예 나에게 일어난 일. 내부 조인이어야합니다! 또는 조인으로 남겨 두십시오. 내부 조인이없는 경우 왼쪽 조인은 모든 tableA 레코드가 업데이트됨을 의미합니다! 이것은 매우 위험합니다!
CMCDragonkai

10
첫 번째 감사합니다 (y). 이 답변은 7 세 이상입니다. 왜 아무도 두 번째가 MySQL과 같은 일부 데이터베이스에서 작동하지 않는다고 말했는지 믿을 수 없습니다. 이 오류가 발생합니다 :You can't specify target table ___ for update in FROM clause SQL.sql
Jugali Lakota

1
또한 최근까지 첫 번째 접근법은 tableA= 일 때 MySQL에서 작동하지 않았습니다 tableB. 중간 결과를 저장하기 위해 임시 테이블을 작성해야합니다. (마이그레이션 스크립트에 대한 유사한 쿼리를 작성했다)
svvac

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 초 이상입니다.
Chris Dev

1
예, 이것은 가장 빠른 쿼리입니다. BTW WHERE 절도 추가 할 수 있습니다
robinmag

1
항상 좋은 것은 아니지만,이 업데이트가 모든 경우에 작동하지는 않습니다. 실제로 어떤 경우에는 예기치 않은 동작이 발생할 수 있습니다. 이것이 모든 조건을 적용하지 않는 조인이 아닙니다.
Emiliano

114

MySQL에서 쉬움 :

UPDATE users AS U1, users AS U2 
SET U1.name_one = U2.name_colX
WHERE U2.user_id = U1.user_id

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 

트라 아! 잘 작동합니다!

위의 이해를 통해 작업을 수행하기 위해 설정된 필드와 "설정"기준을 수정할 수 있습니다. 검사를 수행 한 다음 임시 테이블로 데이터를 가져온 다음 테이블과 열 이름을 바꾸는 위의 구문을 사용하여 업데이트를 실행할 수도 있습니다.

알려지지 않으면 작동하기를 바랍니다. 나는 당신을 위해 정확한 질문을 쓸 것입니다.


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 필드를 채워야하는데, 액티비티는 단위로 번호가 매겨지고 단위는 레벨 (문자열 ?? N로 식별)로 번호가 매겨져 SKU, 즉 L1U1A1을 사용하여 액티비티를 식별 할 수 있습니다. 그런 다음 해당 SKU는 다른 테이블에 저장됩니다.

activity_id와 product_id의 목록을 얻기 위해 다음을 식별했습니다.

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에 통합하기에는 너무 복잡하다는 것을 알았으므로 임시 테이블을 만들고 그것을 update 문과 결합했다.

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;

누군가가 이것을 유용하게 사용하기를 바랍니다.


두 개의 쿼리는 다중 스레드 환경에서 일관된 결과를 제공하지 않을 수 있습니다.
donald

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/

또는 하위 쿼리로 select를 사용 하여이 작업을 수행 할 수 있습니다

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 서버에 대한 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.