Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: нахождение суммы чисел в поле со строкой
Форумы портала PHP.SU » » Работа с СУБД » нахождение суммы чисел в поле со строкой

Страниц (2): [1] 2 »
 

1. Panoptik - 27 Декабря, 2011 - 19:05:57 - перейти к сообщению
усем приветы.

есть поле varchar в таблице, и в нем записаны числа через запятую, например
2,2,1
1
1,3
5,2

задача стоит в нахождении суммы всех этих чисел
например чтобы результат хранился в отдельном поле
5
1
4
7

возможно ли такое проделать в mysql? из всех вариантов находил только с помощью хранимых процедур, с коими дела не имел, но если они могут принести результат, то можно воспользоваться и этим.
буду благодарен за релизацию решения
2. OrmaJever - 27 Декабря, 2011 - 19:13:02 - перейти к сообщению
к примеру
PHP:
скопировать код в буфер обмена
  1. $arr = explode(',', $row['number']); // делим и записываем в масив
  2.  
  3. for($i=1;$i<sizeof($arr);++$i) { // начиная со 2 числа и до конца
  4.    $arr[0] += $arr[$i]; // плюсуем все к первому числу.
  5. }
  6. echo $arr[0];
3. Panoptik - 27 Декабря, 2011 - 19:14:34 - перейти к сообщению
решение нужно сугубо на sql . ибо полученный результат нужно еще будет сортировать...
4. tuareg - 27 Декабря, 2011 - 19:20:59 - перейти к сообщению
Вот аналог функции EXPLODE в MySQL через процедуру
http://vexell[dot]ru/2010/10/mysql-implode-explode/
5. Panoptik - 27 Декабря, 2011 - 19:30:24 - перейти к сообщению
самое интересное что эту ссылку я сегодня тоже находил, но так как с хранимками не работал, то неного есть неясностей
CODE (SQL):
скопировать код в буфер обмена
  1. DELIMITER //
  2. CREATE PROCEDURE `explode`(IN `mylist` VARCHAR(255))
  3. body:
  4. BEGIN
  5.   IF mylist = '' THEN LEAVE body; END IF;
  6.  
  7.   SET @saTail = mylist;
  8.  
  9.   WHILE @saTail != '' DO
  10.     SET @sHead = SUBSTRING_INDEX(@saTail, ',', 1);
  11.     SET @saTail = SUBSTRING( @saTail, LENGTH(@sHead) + 2 );
  12.     ## Тут любой Ваш код
  13.     ## Для примера добавление новых ID пользователей в таблицу users
  14.     INSERT INTO users (id) VALUES (@sHead);
  15.   END WHILE;
  16.  
  17. END//
  18. DELIMITER ;


я понимаю 50% этого кода, но вот операция инсерт мне ни к чему. как бы ее заменить чтобы просто я вызвал эту процедуру и получил поле в таблице с суммой, например
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT *, call explode(`row_count`) AS `total_count` FROM `my_table` ORDER BY `total_count`
6. tuareg - 27 Декабря, 2011 - 19:36:13 - перейти к сообщению
CODE (SQL):
скопировать код в буфер обмена
  1.  
  2. DELIMITER //
  3. CREATE PROCEDURE `explode`(IN `mylist` VARCHAR(255))
  4. body:
  5. BEGIN
  6.   IF mylist = '' THEN LEAVE body; END IF;
  7.  
  8.   SET @saTail = mylist,@countNum = 0;/*Добавляем еще одну переменную*/
  9.  
  10.   WHILE @saTail != '' DO
  11.     SET @sHead = SUBSTRING_INDEX(@saTail, ',', 1);
  12.     SET @saTail = SUBSTRING( @saTail, LENGTH(@sHead) + 2 );
  13.     SET @countNum= @countNum+@sHead;/*Производим сложение*/
  14.   END WHILE;
  15.   SELECT @countNum; /*Выводим ее*/
  16. END//
  17. DELIMITER ;
  18.  
7. armancho7777777 - 27 Декабря, 2011 - 19:38:16 - перейти к сообщению
OrmaJever пишет:
к примеру
PHP:
скопировать код в буфер обмена
  1. $arr = explode(',', $row['number']); // делим и записываем в масив
  2.  
  3. for($i=1;$i<sizeof($arr);++$i) { // начиная со 2 числа и до конца
  4.    $arr[0] += $arr[$i]; // плюсуем все к первому числу.
  5. }
  6. echo $arr[0];


Ну Вы даёте даёте OrmaJever))

PHP:
скопировать код в буфер обмена
  1.  
  2.  // Не мешалобы для начала возможные пробелы удалить
  3. $number = str_replace(' ', '', $row['number']);
  4.  
  5. // Формируем массив
  6. $arr = explode(',', $number);
  7.  
  8.  // Вычисляем сумму всех элементов массива
  9. $s = array_sum($arr);
  10.  
  11. echo $s;
  12.  
8. Panoptik - 27 Декабря, 2011 - 19:39:26 - перейти к сообщению
спасибы! щас протестируем. я надеюсь использование я правильно делаю:
call explode(`row_count`) , где row_count столбец со строковыми данными?
9. Champion - 27 Декабря, 2011 - 19:41:46 - перейти к сообщению
А какая СУБД? И с чего такая потребность?
10. Panoptik - 27 Декабря, 2011 - 19:42:48 - перейти к сообщению
mysql. формирование отчетных данных с возможностью сортировки по различным параметрам
11. DeepVarvar - 27 Декабря, 2011 - 19:44:43 - перейти к сообщению
Ээээ... А так:
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT f1,f2,f3,(f1+f2+f3) fsum FROM tbl

???
12. tuareg - 27 Декабря, 2011 - 19:45:35 - перейти к сообщению
А если вам вообще в запросе, то нужна ф-я а не процедура.
CODE (SQL):
скопировать код в буфер обмена
  1.  
  2. DELIMITER //
  3. CREATE FUNCTION `explode`(`mylist` char(50)) RETURNS int(11)
  4. BEGIN
  5.  DECLARE returnCount int(3);
  6.  IF mylist = '' THEN LEAVE body; END IF;
  7.  SET @saTail = mylist;/*Добавляем еще одну переменную*/
  8.  WHILE @saTail != '' DO
  9.     SET @sHead = SUBSTRING_INDEX(@saTail, ',', 1);
  10.     SET @saTail = SUBSTRING( @saTail, LENGTH(@sHead) + 2 );
  11.     SET returnCount= returnCount+@sHead;/*Производим сложение*/
  12.   END WHILE;
  13.  RETURN returnCount;
  14. END//
  15. DELIMITER ;
  16. /*И тогда запрос*/
  17. SELECT *, `explode`(`row_count`) AS `total_count` FROM `my_table` ORDER BY `total_count`
  18.  

Вот как-то так. Писал прямо тут, так что не обессудьте.
13. DeepVarvar - 27 Декабря, 2011 - 19:47:10 - перейти к сообщению
А я чот не то написал..
14. Panoptik - 27 Декабря, 2011 - 19:54:27 - перейти к сообщению
tuareg большое спасибо вам за исчерпывающий ответ. плюсую
(Добавление)
кстати вот эти DELIMETR это обязательные вещи? и нужно ли каждый раз выполнять функцию, или один раз выполнить, а после она будет храниться?
15. tuareg - 27 Декабря, 2011 - 20:09:00 - перейти к сообщению
Panoptik пишет:
DELIMETR это обязательные вещи?

Да это разделители. Т.е они необходимы, для того чтобы можно было использовать ;
в функции или в процедуре.
Panoptik пишет:
и нужно ли каждый раз выполнять функцию, или один раз выполнить, а после она будет храниться?

Нет, ее достаточно создать один раз и все. Потом она уже будет выполняться сама.
хранятся они в таблице 'information_schema'.(по моему Улыбка ).
Плюсом использования в данном случае функции, является то, что она после первого запроса в соединении попадет в КЭШ mySQL.(план выполнения ф-и) И далее затраты на ее выполнение будут мизерны.
P.S Единственное, что я бы сделал, это не сортировал на стороне MySQl, а сортировку производил уже на PHP. Потому что в данном запросе, будет осуществляться полное сканирование таблицы, потом создание временной таблицы, ее сортировка и только потом вывод рез-та.

 

Powered by ExBB FM 1.0 RC1