2016-11-08 4 views
-1

レッツは、私は、テーブル格納し、調査結果を持っていると言うと、構文は次のようになります。SQLに複数の列の値の出現を数える方法はありますか?

id | q1 | ..... | q30 | created_at 

created_atは、タイムスタンプ列で、他のすべての整数フィールドです。

今月の調査結果が必要です。一つの質問のためにそれを行うために、私が持っている:データがさらに計算し、最終的にいくつかのデータ表示のための私のPHPスクリプトに渡されます

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 

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 

リターンのようなものになります。

30列の計算を行うには、別の質問に対してこのクエリを30回実行する方法もあります。

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 

1つのクエリでこれを行う方法があります:出力は次のようなものになるように、単一のクエリでそれを行う方法がある場合、私は疑問に思って?はいの場合、このパフォーマンスは改善されますか?

+1

Google - > SQLピボット – sagi

+0

ありがとうございます。 – cytsunny

+0

Googleが好きなのですが、データ表示の問題は一般にアプリケーションレベルのコードで解決されます(利用可能であることが前提です)。そうですね、あなたのデザインをNORMALIZEしてください。 – Strawberry

答えて

2

これは、クエリがどのように見えるかです:

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 

そして、あなたのクエリは、単純に次のようになります。

select 
    year(created_at) as year, 
    month(created_at) as month, 
    q_type, 
    q_value, 
    count(*) 
from survey_table 
group by year(created_at), month(created_at), q_type, q_value; 

あなたは、書式設定を行います。すなわち、データをグリッドに入れます。これはより柔軟性があります。なぜなら、問合せでは、いくつのqタイプが存在し、いくつのq値が存在するかを知る必要がないからです。

+0

この作業ではこの表のデザインが簡単になりますが、1回の調査ですべての結果を得ることは困難です。また、実際のアプリケーションでは、答えが整数ではないという別のタイプの質問があるため、この設計は不可能です。 – cytsunny

+0

さて、最初のクエリを使用してください。ただし、可能なすべてのq値(例では1〜3)を事前に知る必要があります。または、クエリを動的に構築します。あるいは、実際には30個のクエリを記述し、それらを 'UNION ALL'で単一のクエリに結合します。 –

+0

@cytsunnyこれにより、すべてのことが簡単になります。デザインを非常に微妙に微調整する必要があるかもしれません。それだけです。 – Strawberry

0

ここでは、私が他の答えに対するコメントで述べたUNION ALLのクエリです。クエリを書くときにどのようなq値が存在するかを知る必要はなく、UNION ALLのために、(不要なラウンドトリップを避けるために)実行されるクエリは1つだけです。

現在のテーブル設計のため、まだ高速なクエリではありません。

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; 
関連する問題