2015-07-20 42 views
0

here處有類似的問題,但似乎太舊了,因爲回答在2009年提供,只收到7個支持。我相信有一個更好的策略。如何使用一個查詢根據相對值更新表列

表如下:

id weight cost 
1 1.2  0 
2 2.5  0 
3 2.9  0 
... 

其中重量和成本是一個物品的重量和成本。現在我想通過給出總成本N來更新每個id的成本。每個id的成本是基於其相對於總重量的相對權重的總成本的一小部分。

以一個表僅具有三排如上,總重量爲1.2 + 2.5 + 2.9 = 6.6,因此,IDS 1,2和成本3是:

N*1.2/6.6 
N*2.5/6.6 
N*2.9/6.6 

有一種方法對於我使用單個查詢來執行此更新?我嘗試了一些東西,但它給了我錯誤信息SQLSTATE[HY000]: General error: 1111 Invalid use of group function;這裏是我的代碼,我想知道到底爲什麼它不能做到這樣:

UPDATE `table` 
    SET `cost` = `cost` + :total_cost * `weight`/SUM(`weight`) 
WHERE 1 
+0

@TimBiegeleisen,感謝您指出。但是這個問題似乎太老了,因爲答案是在2009年提供的,只得到7個支持。我相信有更好的答案。 – Dainy

+0

在更新過程中,MySQL是否改變了自己的限制?如果是這樣,那麼你有另一種選擇。 –

回答

0

像說here,處理這種情況的典型方式是做多表更新。你應該cross join來計算權重之和的子查詢:

UPDATE 
    tableName tableNameToUpdate 
CROSS JOIN 
    (SELECT 
     SUM(innerTableName.weight) AS sumWeight 
    FROM 
     tableName AS innerTableName 
    ) tableNameSub 
SET 
    tableNameToUpdate.cost = :total_cost * 
          (tableNameToUpdate.weight/tableNameSub.sumWeight) 

在實踐中,如果你想要做一個交叉連接,然後使用交叉連接。 它比要好得多:

from A, B 
+0

你測試了這段代碼嗎? –

+0

越來越近:) – Drew

+0

改變了我的答案交叉連接 – AlexB

1
create table tbl1 
(
id int auto_increment primary key, 
weight decimal(10,4) not null, 
cost decimal(10,4) not null 
); 

insert tbl1(weight,cost) values (1.2,0),(2.5,0),(2.9,0),(8.1,0),(1.1,0),(1.2,0); 

-- assume total shipping cost (N) = 17.20 
update tbl1 t1, 
(select sum(weight) as tot_weight from tbl1) t2 
set cost=17.20*(t1.weight/t2.tot_weight) 

select * from tbl1; 

select sum(cost) from tbl1; 
-- 17.1999 (close enough :>) 
相關問題