2014-06-12 2 views
0

가지고있는 문제의 예가 있습니다. 데이터베이스 테이블은 평소와 약간 다르지만이 방법으로 설정해야합니다.복잡한 MySql 업데이트 가입 쿼리

항목 : 아이디, ORDER_ID, 다른 분야

Items_Drinks : 아이디, 음료, 다른 분야

주문 : 아이디, 다른 분야

Orders_Drinks : 아이디, 음료, 다른 분야

Orders_Drinks id 필드와 동일한 order_id를 가진 Items_Drinks drinks 필드의 합계로 Orders_Drinks 테이블을 업데이트 할 업데이트 쿼리가 있어야합니다.

Items: 1 1 ... 
Items: 2 1 ... 
Items_Drinks: 1 4 ... 
Items_Drinks: 2 5 ... 

Orders: 1 ... 
Orders_Drinks: 1 9 ... 

Orders_Drinks 현재 정확하지만 내가 5 일의 ID로 Items_Drinks를 업데이트한다면, 나는 이드 1 Orders_Drinks을 얻기 위해 업데이트 명령을 필요 동일한 10

이 될 것이다 명령이 Orders_Drinks의 모든 레코드를 업데이트하는 것이 가장 좋습니다.

내 데이터베이스가 일반적인 것은 아니지만 제 신청서에 필요하다는 것을 알고 있습니다. Drinks 테이블이 모든 항목에 필요하지 않기 때문입니다. Drinks 테이블에는 5000 개가 넘는 필드가 있으므로 모든 레코드에 이러한 세부 정보가 있으면 데이터베이스가 커지고 실제 이유없이 느려집니다. 제발 데이터베이스를 재구성하라는 말을하지 마십시오. 이것이 필요합니다.

현재 C# 프로그램에서 루프를 사용하여 필요한 것을 수행하지만 명령이 1 개이면 많은 시간을 절약 할 수 있습니다!

여기에 최선의 시도가 있지만 "잘못된 그룹 기능"오류가 발생합니다.

update Orders_Drinks join Items on Items.order_id=Orders_Drinks.id join Items_Drinks on Items_Drinks.id=Items.id set Orders_Drinks.drinks=sum(Item_Drinks.drinks); 
+0

5000 개의 필드가있는 테이블? 스키마 전체가 다시 생각해야 할 필요가 있다고 생각합니다. 나는 당신이 당신의 질문에서 "이 방법이어야한다"고 말한 것을 알고 있습니다. 그러나 제 추측은 그것이 그렇게 할 필요는 없다는 것입니다. 아마도 관계형 저장소는 본질적으로 스키마가없는 무언가가 필요한 경우 실제로 필요한 것이 아닙니다. –

답변

1

나는 이것이 당신이 원하는 것이라고 생각합니다.

편집 됨 : 1

이의 행 ID의 Order_Drinks 테이블에 대해 당신에게 9 총을 주어야한다

UPDATE `Order_Drinks` a 
SET a.`drinks` = (SELECT SUM(b.`drinks`) FROM `Items_Drinks` b INNER JOIN `Items` c ON (b.`id` = c.`id`) WHERE a.`id` = c.`order_id`) 

은 가정입니다

그 Orders.id == Orders_Drinks.id 그 Items.id == Items_Drinks.id.

+0

이것은 item_drinks 레코드 중 하나의 결과 만 가져 오며 합계하지 않습니다. 뭔가 빠져 있어야합니다. – user2843198

+0

네 말이 맞아. 미안. 나는 내 대답을 편집했다. – Rylonian

+0

와우, 거대한 감사합니다! 이것은 내가 필요한 것입니다! – user2843198

1

집합을 수행해야합니다.

이 같은
update Orders_Drinks od join 
     (select i.order_id, sum(id.drinks) as sumdrinks 
     from Items i join 
      Items_Drinks id 
      on id.id = i.id 
     ) iid 
     on iid.order_id = od.id 
    set od.drinks = iid.sumdrinks; 
+0

이것은 훨씬 더 효율적인 방법입니다. – Nate

+0

@Nate. . . 왜 이것이 특히 효율적이지 않다고 생각하십니까? 많은 경우, 그 성과는 수용된 대답과 비교 될 것입니다. –

0

뭔가가 drinks 요약 필드의 현재 값과 함께 orders_drinks 테이블에서 id을 반환하고,에서 파생 된 새로운 요약 값 : 당신은 update 문의 join 부분에서이 작업을 수행 할 수 있습니다 관련 items_drinks 테이블

(외래 키 열 이름은 패턴이다 결석 외부 키 컬럼의 이름, 나는 가정했습니다 : "referenced_table_id")

가 우리가 SELECT 질의 결과를 얻을이 작성되면

SELECT od.id 
    , od.drinks    AS old_drinks 
    , IFNULL(td.tot_drinks,0) AS new_drinks 
    FROM orders_drinks od 
    LEFT 
    JOIN (SELECT di.orders_drinks_id 
       , SUM(di.drinks) AS tot_drinks 
      FROM items_drinks di 
      GROUP BY di.orders_drinks_id 
     ) td 
    ON td.orders_drinks_id = od.id 

우리 우리는 그것을 UPDATE 문으로 변경할 수 있습니다.SELECT ... FROMUPDATE 키워드로 바꾸고 SET 절을 추가하여 drinks 열에 값을 할당하거나 바꿉니다.

예컨대

UPDATE orders_drinks od 
    LEFT 
    JOIN (SELECT di.orders_drinks_id 
       , SUM(di.drinks) AS tot_drinks 
      FROM items_drinks di 
      GROUP BY di.orders_drinks_id 
     ) td 
    ON td.orders_drinks_id = od.id 
    SET od.drinks = IFNULL(td.tot_drinks,0) 

(참고 :.. IFNULL 함수는 선택 사항입니다 난 그냥이 발견 items_drinks에 일치하는 행이없는, 또는 전체가 NULL 때마다 때마다 0의 값을 대체하는 데 사용)

이 의지 orders_drinks 테이블에서 업데이트해야하는 모든 행을 업데이트하십시오. 만 orders_drinks에서 특정 행을 업데이트하고 싶었 경우 WHERE 절은 오히려 모든 행보다,합니다 (SET 절 후) 추가 할 수 있습니다 :

WHERE od.id = 1 

을 다시,이에 도착, 처음에 작업 SELECT 문을 얻을 업데이트 할 테이블의 키와 함께 열에 할당 할 새 값을 반환합니다. 일단 작동하면 UPDATE 문으로 변환하여 새 값을 반환하는 식을 SET 절로 이동하십시오.