Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 有没有办法计算SQL中多列值的出现次数?_Mysql_Sql - Fatal编程技术网

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组合成一个查询,这会使一切变得更简单。您可能只需要非常非常轻微地调整设计,仅此而已。