2016-12-16 1 views
1

나는이 문제로 인해 지금 며칠 동안 나를 죽이고 있습니다.MYSQL 여러 개의 고유 한 열을 기준으로 삭제

모든 주문 처리 테이블이 있습니다. 들어오는 모든 주문에 대한 표가 있습니다.

새 테이블의 주문을 효과적으로 수정해야합니다. 새 테이블의 주문은 이미 기본 테이블에있는 주문과 계속해서 업데이트되므로 완료하지 못합니다. 같은 순서로 여러 번. 아마 당신은 말할 수

$sql = "DELETE 
FROM 
    `orders_new` 
WHERE 
    `order` IN (
     SELECT DISTINCT 
      `order` 
     FROM 
      `orders_all` 
    ) 
AND `name` IN (
    SELECT DISTINCT 
     `name` 
    FROM 
     `orders_all` 
) 
AND `jurisdiction` IN (
    SELECT DISTINCT 
     `jurisdiction` 
    FROM 
     `orders_all` 
)"; 

가, 내가 원하는 : 우리는 새로운 주문의 배치를 얻을 후

이 내가 현재 완료된 주문의 테이블을 참조 교차하는 시도에서 실행되는 쿼리입니다 order, namejurisdiction과 같은 행이 이미 "orders_all"테이블에있는 "orders_new"테이블에서 행을 삭제할 수 있습니다.

이런 종류의 쿼리를 처리하는 것이 올바른 방법입니까?

+0

주문 필드에 무엇이 있습니까 ?? ID 또는 제품 이름 또는 제품 코드입니까? –

+0

고객/고객이 제공하는 주문 ID이며 변경할 수 없습니다. – Justin

답변

1

음, 올바른 방법은 여러 가지에 따라 달라집니다. 하지만 먼저 나는 두 테이블로 나누는 것을 좋아하지 않습니다. 이 경우 나는 상태를 식별 할 수있는 컬럼을 도입 할 것이다. 그것들은 "새로운", "진행중인", "완료된"것입니다. 그런 식으로 하나의 레코드를 하나의 레코드로 저장해야합니다. 하지만 쿼리가 정상적으로 수행되지만 성능을 확인해야합니다. 다음을보십시오 : https://sqlperformance.com/2012/12/t-sql-queries/left-anti-semi-join 정확히는 아니지만 매우 유사합니다.

다른 점 : 왜 DISTINCT를 사용합니까? 이는 "주문"이 고유 한 식별자가 아니라는 것을 의미합니다.

편집 내용에 따라 복합 키 "주문", "이름", "관할 구역"으로 주문을 식별합니다. 이것은 정말로 열쇠, 전체 열쇠 그리고 열쇠 ​​일 뿐이므로 당신을 도와줍니다. 그렇지 않으면 많은 레코드를 삭제할 수 있습니다. 그러나 귀하의 질의는 주문, 이름 및 관할권이 다른 기록에있는 테이블 순서에서 발견 될 수있는 모든 명령을 삭제합니다. 따라서 귀하의 질의는 거짓입니다. 쿼리의 변형이

DELETE order_new 
FROM 
    order_new 
    INNER JOIN 
    order_all ON order_all.order = order_new.order 
        AND order_all.name = order_new.name 
        AND order_all.jurisdiction = order_new.jurisdiction 

수 있습니다하지만, 진짜 문제는 당신의 ER 모델하다는 것을 말하는

.

+0

그의 쿼리는 대부분 확인하지 않을 것입니다; 그러나 나는이 두 테이블이 잘못되었다는 감정을 두 번째로 나타냅니다. – Uueerdo

+0

"주문"은 고유 한 식별자가 아니지만 고객이 당사에 제공하므로이 사실을 알리지 못합니다. – Justin

+0

@justin 그런 경우 srrogate 키를 도입해야합니다. 그러나 ... 고객조차도 주문을 고유하게 식별 할 수있는 방법이 있어야합니다. –

0

당신은 같은 구성 DELETE - JOIN에 그 변환해야

DELETE `orders_new` 
FROM `orders_new` 
INNER JOIN `orders_all` ON `orders_new`.`order` = `orders_all`.`order` 
AND `orders_new`.`name` = `orders_all`.`name` 
AND `orders_new`.`jurisdiction` = `orders_all`.`jurisdiction`; 
+1

세 개의 열이 모두 값과 일치하는 행을 삭제하려는 것이므로 "OR"대신 "AND"조건을 사용해야하지 않습니까? – Justin

+0

@Justin, Yes 절대적으로 ... 그 점을 놓친 것 – Rahul

0

아니, 같은 order, namejurisdiction, 어떤 기록이 그 기록이 다른 경우에도이 어디에 어떤 기록을 삭제 쿼리 서로. 즉, 의 한 행에 같은 order이 있고 다른 행에 동일한 name이 있고 세 번째 행에 동일한 jurisdiction이 있으면 orders_new의 행이 삭제됩니다. 당신은 당신이 원하는 것보다 더 많은 것을 삭제할 가능성이 아주 높습니다. 대신이 더 적절할 것 :

DELETE FROM `orders_new` 
WHERE (`order`, `name`, jurisdiction`) IN (
    SELECT `order`, `name`, `jurisdiction` 
    FROM `orders_all` 
) 

아니면

DELETE FROM `orders_new` 
WHERE EXISTS (
    SELECT 1 
    FROM `orders_all` AS oa 
    WHERE oa.`order` = `orders_new`.`order` 
    AND oa.`name` = `orders_new`.`name` 
    AND oa.`jurisdiction` = `orders_new`.`jurisdiction` 
) 
관련 문제