2014-10-06 2 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

Вы должны исправить свой формат данных, поэтому у вас есть таблица правильного соединения (а строка для каждого элемента и идентификатор). Хранение числовых идентификаторов в строковых списках - очень плохая структура данных. Кроме того, ваш запрос в любом случае неверен. –

+1

Гордон прав. Я настоятельно рекомендую вам не принимать какие-либо ответы и сначала фиксировать способ создания базы данных. То, что у вас здесь, является отношением «многие ко многим», и оно решается с помощью таблицы соединения/соединения. Почитайте о взаимоотношениях «многие-ко-многим», поскольку вы найдете их относительно обычными и правильно построите свою базу данных, что сэкономит вам много головных болей. – Alternatex

+0

Я хотел бы реструктурировать базу данных, но я не могу. Мне нужно получить общую сумму по текущей структуре. –

ответ

0

Я решил проблему самостоятельно. Я написал функцию в SQL. Вызывается это «calcSum», и есть параметр «список» один текст:

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 | 
+--------+----------+--------------+ 
Смежные вопросы