まず、これはプレゼンテーション ロジック (php コード) で処理する問題のように感じられると思います。ただし、SQL はそのような結果を生成する可能性があります。あなたは2つの異なることを達成しようとしています。
まず、テーブルを探していPIVOT
ます。MySQL はこのコマンドをサポートしていませんが、とPIVOT
でシミュレートできます。これは、潜在的なカテゴリの数がわかっている場合はうまく機能しますが、あなたの場合は機能しません。MAX
CASE
次に、行の合計を取得し、次に最終的な合計行を取得します。 繰り返しますが、これはプレゼンテーション層で処理する方が適切です。
ただし、 を使用すると、表と行Dynamic SQL
の両方のPIVOT
合計を取得できます。サンプルコードは次のとおりです。
まず、PIVOT 変数 @sql を作成します。
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'COUNT(IF(category = ''', category, ''',1,NULL)) AS ', category)
) INTO @sql
FROM (
SELECT *,
@rn:=IF(@prevMonthYear=CONCAT(YEAR(datetime),'-',MONTH(datetime)),@rn+1,1) rn,
@prevMonthYear:=CONCAT(YEAR(datetime),'-',MONTH(datetime)) dt
FROM yourtable JOIN (SELECT @rn:=0,@prevParent:=0) t
) t
;
次に、Row Summary 変数 @totsql を作成します。
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'SUM(', category, ') AS sum_', category)
) INTO @totsql
FROM (
SELECT *,
@rn:=IF(@prevMonthYear=CONCAT(YEAR(datetime),'-',MONTH(datetime)),@rn+1,1) rn,
@prevMonthYear:=CONCAT(YEAR(datetime),'-',MONTH(datetime)) dt
FROM yourtable JOIN (SELECT @rn:=0,@prevParent:=0) t
) t
;
すべてをまとめる:
SET @sql = CONCAT('SELECT dt,
', @sql, ', COUNT(1) total
FROM (
SELECT *,
@rn:=IF(@prevMonthYear=CONCAT(YEAR(datetime),''-'',MONTH(datetime)),@rn+1,1) rn,
@prevMonthYear:=CONCAT(YEAR(datetime),''-'',MONTH(datetime)) dt
FROM yourtable JOIN (SELECT @rn:=0,@prevParent:=0) t
) t
GROUP BY dt
UNION
SELECT ''Totals'',', @totsql, ', SUM(total)
FROM (
SELECT dt,
', @sql, ', COUNT(1) total
FROM (
SELECT *,
@rn:=IF(@prevMonthYear=CONCAT(YEAR(datetime),''-'',MONTH(datetime)),@rn+1,1) rn,
@prevMonthYear:=CONCAT(YEAR(datetime),''-'',MONTH(datetime)) dt
FROM yourtable JOIN (SELECT @rn:=0,@prevParent:=0) t
) t
GROUP BY dt
) t2
;');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
結果:
MONTH FISH POTATO PINEAPPLE TOTAL
2009-1 3 1 0 4
2009-2 0 1 1 2
Totals 3 2 1 6