2014-10-06 74 views
0

我有兩個表 在第一個表,「項目」,存放物品價格:MySQL的總和多重複的行

id price 
1 40 
2 55 
3 70 

在第二個表中,「套」,儲存項目的集合,和物品,包含在集合中,存儲爲逗號分隔列表:

id items 
1 1,2,3 
2 2,2,3,3 
3 1,2,1,2 

我需要獲取套餐的總價格。

SELECT id, (
    SELECT SUM(price) 
    FROM `items` AS i 
    WHERE i.id IN (s.items) 
) AS total_price 
FROM `sets` AS s 

但是,如果在「s.items」中存在重複,總和是錯誤的。

P.S.對不起我的英語不好。

+2

讓你有一個恰當的結合表,您應該解決您的數據格式(爲每個項目和id行)。將數字標識存儲在字符串列表中是非常糟糕的數據結構。另外,你的查詢不正確。 – 2014-10-06 10:48:10

+1

戈登是對的。我敦促你不要接受任何答案,並首先解決你的數據庫構造方式。你在這裏得到的是一個多對多的關係,它使用連接/連接表來解決。閱讀多對多關係,因爲您會發現它們比較常見,並以適當的方式構建數據庫將爲您節省很多麻煩。 – Alternatex 2014-10-06 10:55:16

+0

我想重組數據庫,但我不能。我需要總結當前的結構。 – 2014-10-06 14:11:32

回答

0

我自己解決了問題。 我在SQL中編寫函數。把它稱爲「calcSum」,它有一個TEXT參數「清單」:

BEGIN 
DECLARE strLen INT DEFAULT 0; 
DECLARE subStrLen INT DEFAULT 0; 
DECLARE totalSum INT DEFAULT 0; 
DECLARE x INT DEFAULT 0; 

IF list IS NULL THEN 
    SET list = ''; 
END IF; 

traversing: 
LOOP 
    SET strLen = CHAR_LENGTH(list); 
    SELECT price INTO x FROM items WHERE id = SUBSTRING_INDEX(list, ',', 1); 
    SET totalSum = totalSum + x; 
    SET subStrLen = CHAR_LENGTH(SUBSTRING_INDEX(list, ',', 1)) + 2; 
    SET list = MID(list, subStrLen, strLen); 
    IF list = '' THEN 
     LEAVE traversing; 
    END IF; 
END LOOP traversing; 

RETURN totalSum; 
END 

而且隨着新功能的更改信息查詢

SELECT id, calcSum(s.items) AS total_price 
FROM `sets` AS s 
0
"item" 
item_id price 
1  40 
2  55 
3  70 

"sets" 
set_id set_name 
1  blah 
2  wow 
3  awesome 

"set_item" 
set_item_id set_id item_id 
1    1  1 
2    1  2 
3    1  3 
4    2  2 
5    2  2 
6    2  3 
7    2  3 
8    3  1 
9    3  2 
10   3  1 
11   3  2 

select s.set_id,s.set_name, sum(i.price) 
from set_item si 
join sets s on si.set_id = s.set_id 
join item i on si.item_id = i.item_id 
group by si.set_id; 

+--------+----------+--------------+ 
| set_id | set_name | sum(i.price) | 
+--------+----------+--------------+ 
|  1 | blah  |   165 | 
|  2 | wow  |   250 | 
|  3 | awesome |   190 | 
+--------+----------+--------------+