PHP SQL SELECT总和(值)WHERE x LIKE'%$ month%' (的foreach)

时间:2017-07-04 10:50:58

标签: php mysql datetime foreach aggregate-functions

我有一张桌子:

user_id |       month       | value
    1   | firstname_1_2017  |   5 
    1   | secondname_1_2017 |   4
    1   | firstname_2_2017  |   7 
    1   | secondname_2_2017 |   8
    1   | firstname_3_2017  |   5 
    1   | secondname_3_2017 |   4
    1   | firstname_4_2017  |   7 
    1   | secondname_4_2017 |   8

我需要总和"价值"与foreach一起每个月。

firstname_1_2017 + secondname_1_2017 = 9

firstname_2_2017 + secondname_2_2017 = 15

我有几个月的阵列:

$array_months = array( '1','2','3','4','5','6','7','8','9','10','11','12' );

所以我写了(在php中):

SELECT sum(value)
FROM table
WHERE user_id = $user_id
AND month LIKE '%_$array_months_2017%'

当我写一个foreach时,结果是每个月重复所有值的相同总和(例如:1月48点,2月48点,3月48点......)。

我喜欢这个结果与foreach:

你有" 9"一月份的分数

你有" 15"二月点数

等...

2 个答案:

答案 0 :(得分:1)

您应该考虑将数据库设计更改为将用户名称与月份和年份分开。

不是一个好的方法,但解决方案是从month字符串中提取月份,并将其分组以计算每个月的总和。

SELECT SUBSTR(month, LOCATE('_', month) + 1) AS month_year, SUM(value)
FROM users
WHERE user_id = 1
GROUP BY month_year;

Working Fiddle

答案 1 :(得分:0)

您可以使用the SUBSTRING_INDEX() function这样的month列值提取数字,并提供3_2017

SUBSTRING_INDEX('firstname_3_2017', '_', -2)

然后,您可以使用CONCAT()将其转换为 date-ish 字符串,并产生1_3_2017

CONCAT('1_',SUBSTRING_INDEX('firstname_3_2017', '_', -2))

然后,您可以使用DATE将其转换为实际的STR_TO_DATE()值。

STR_TO_DATE(CONCAT('1_',SUBSTRING_INDEX('firstname_3_2017', '_', -2)),'%d_%m_%Y')

很酷,现在你有了一个可以实际使用的数据类型。您现在可以使用聚合查询来获得好东西。利用萨米尔的小提琴:http://sqlfiddle.com/#!9/8aabd/6/0

SELECT 
  SUM(value) value,
  user_id,
  STR_TO_DATE(CONCAT('1_',SUBSTRING_INDEX(month, '_', -2)),'%d_%m_%Y') month_begin
  FROM table
 GROUP BY user_id, STR_TO_DATE(CONCAT('1_',SUBSTRING_INDEX(month, '_', -2)),'%d_%m_%Y')

摘要:month列的简单转换可为您提供有用的信息。

专业提示:在设计表时尽量不要将具有不同含义的值填充到单个列中。了解规范化。

专家提示2:使用实际的DATETIMESTAMPDATETIME值来尽可能存储基于时间的信息。日期算术和基于日期的索引是DBMS服务器的强大部分。