Mysql 有没有办法计算SQL中多列值的出现次数?
假设我有一个存储调查结果的表,语法如下所示:Mysql 有没有办法计算SQL中多列值的出现次数?,mysql,sql,Mysql,Sql,假设我有一个存储调查结果的表,语法如下所示: id | q1 | ..... | q30 | created_at year | month| q1_1 | q1_2 | q1_3 | q2_1 | q2_2 | q2_3 | ... | q30_1 | q30_2 | q30_3 2016 | 11 | 10 | 15 | 2 | 2 | 20 | 5 | ... | 5 | 15 | 7 2016 | 10 | 12 | 2
id | q1 | ..... | q30 | created_at
year | month| q1_1 | q1_2 | q1_3 | q2_1 | q2_2 | q2_3 | ... | q30_1 | q30_2 | q30_3
2016 | 11 | 10 | 15 | 2 | 2 | 20 | 5 | ... | 5 | 15 | 7
2016 | 10 | 12 | 2 | 50 | 25 | 27 | 12 | ... | 20 | 24 | 20
created\u at
是一个时间戳列,其他所有字段都是整数字段
现在我想知道每月的调查结果。为了回答一个问题,我有:
SELECT YEAR(created_at) as year, MONTH(created_at) as month, q1, count(*) as occurrence
FROM survey_table
GROUP BY YEAR(created_at), MONTH(created_at), q1
回报将类似于:
year | month| q1 | occurence
2016 | 11 | 1 | 10
2016 | 11 | 2 | 15
2016 | 11 | 3 | 2
2016 | 10 | 1 | 12
2016 | 10 | 2 | 2
2016 | 10 | 3 | 50
数据将被传递到我的PHP脚本进行进一步计算,最后显示一些数据
要对30列进行计算,一种方法是对不同的问题执行30次此查询。我想知道是否有一种方法可以在单个查询中实现这一点,以便输出如下所示:
id | q1 | ..... | q30 | created_at
year | month| q1_1 | q1_2 | q1_3 | q2_1 | q2_2 | q2_3 | ... | q30_1 | q30_2 | q30_3
2016 | 11 | 10 | 15 | 2 | 2 | 20 | 5 | ... | 5 | 15 | 7
2016 | 10 | 12 | 2 | 50 | 25 | 27 | 12 | ... | 20 | 24 | 20
有没有一种方法可以在一个查询中实现这一点?如果是,此性能是否更好?以下是查询的外观:
select
year(created_at) as year,
month(created_at) as month,
count(q1 = 1) as q1_1,
count(q1 = 1) as q1_2,
count(q1 = 1) as q1_3,
count(q1 = 2) as q2_1,
...
count(q30 = 3) as q30_3
from survey_table
group by year(created_at), month(created_at);
然而,似乎最好改变您的桌子设计:
q_type | q_value |created_at
-------+---------+----------
1 | 1 | 2016-10-05
2 | 3 | 2016-10-05
3 | 1 | 2016-10-05
4 | 2 | 2016-10-05
...
30 | 1 | 2016-10-05
...
29 | 1 | 2016-10-08
30 | 2 | 2016-10-08
您可以使用PHP进行格式化,即将数据放入网格中。这更灵活,因为您的查询不再需要知道存在多少q类型和q值。这是我在对另一个答案的评论中提到的
联合所有查询。在编写查询时,您不必知道存在什么q值,而且由于UNION ALL
只执行一个查询(以避免不必要的往返)
由于当前的表设计,它仍然不是一个快速查询
select year(created_at) as year, month(created_at) as month, 'Q1', q1, count(*) as cnt
from survey_table
group by year(created_at), month(created_at), q1
UNION ALL
select year(created_at) as year, month(created_at) as month, 'Q2', q2, count(*) as cnt
from survey_table
group by year(created_at), month(created_at), q2
UNION ALL
...
UNION ALL
select year(created_at) as year, month(created_at) as month, 'Q30', q30, count(*) as cnt
from survey_table
group by year(created_at), month(created_at), q30;
Google->SQL Pivoting感谢您提供关键字。如果您愿意,请使用Google,但数据显示问题通常最好通过应用程序级代码(假设可用)来解决-哦,并使您的设计正常化。确实,此表设计对于此操作来说会更容易,但很难从单个调查中获取所有结果。另外,在实际应用中,还有其他类型的问题的答案不是整数,所以这种设计是不可能的。但是,您需要事先知道所有可能的q值(在您的示例中为1到3)。或者动态地构建查询。或者真的编写30个查询,并将它们与UNION ALL
@cytsunny组合成一个查询,这会使一切变得更简单。您可能只需要非常非常轻微地调整设计,仅此而已。