我有一张桌子:
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"二月点数
等...
答案 0 :(得分:1)
您应该考虑将数据库设计更改为将用户名称与月份和年份分开。
不是一个好的方法,但解决方案是从month
字符串中提取月份,并将其分组以计算每个月的总和。
SELECT SUBSTR(month, LOCATE('_', month) + 1) AS month_year, SUM(value)
FROM users
WHERE user_id = 1
GROUP BY month_year;
答案 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:使用实际的DATE
,TIMESTAMP
或DATETIME
值来尽可能存储基于时间的信息。日期算术和基于日期的索引是DBMS服务器的强大部分。