例。私のデータはテーブル名:BIKEからのものです
Bike_No Repair_Date Repair_Cost
-------- ----------- ------------
ABC1234 2013-01-05 50.00
BMX5678 2013-02-04 75.00
ABC1234 2013-01-25 20.00
BON3333 2013-03-06 80.00
DEB1111 2013-08-04 40.00
ABC1234 2013-09-06 50.00
日付範囲(例:2013年1月1日から2013年3月31日まで)に基づいて各自転車の修理費を確認したいのですが、結果テーブルには、Bike_Noと影響を受ける月を列として修理費を表示する必要があります。クエリされた日付範囲に基づいて、影響を受ける月を列としてどのように生成しますか?
残念ながら、MySQLにはPIVOT関数がないため、データを次の形式に変換しようとしているようです。
+---------+-----------------+-----------------+-----------------+
| bike_no | repair_cost_Jan | repair_cost_Feb | repair_cost_Mar |
+---------+-----------------+-----------------+-----------------+
| ABC1234 | 70 | 0 | 0 |
| BMX5678 | 0 | 75 | 0 |
| BON3333 | 0 | 0 | 80 |
+---------+-----------------+-----------------+-----------------+
その場合、MySQLでは、CASE式とともに集計関数を使用して、データの行を列に変換する必要があります。
返される月数がわかっている場合は、次のようなクエリを簡単にハードコードできます。
select bike_no,
sum(case when month(repair_date) = 1 then repair_cost else 0 end) repair_cost_Jan,
sum(case when month(repair_date) = 2 then repair_cost else 0 end) repair_cost_Feb,
sum(case when month(repair_date) = 3 then repair_cost else 0 end) repair_cost_Mar
from bike
where repair_date >= '2013-01-01'
and repair_date <= '2013-03-31'
group by bike_no;
SQL Fiddle with Demo を参照してください。
しかし、あなたの場合、開始日と終了日をクエリに変更したいようです。その場合は、実行される 動的SQLを生成するために準備されたステートメント を使用する必要があります。
SET @sql = NULL;
set @startdate = '2013-01-01';
set @enddate = '2013-03-31';
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'sum(CASE WHEN month(repair_date) = ',
month(repair_date),
' THEN repair_cost else 0 END) AS `repair_cost_',
monthname(repair_date), '`'
)
) INTO @sql
FROM bike
where repair_date >= @startdate
and repair_date <= @enddate;
SET @sql
= CONCAT('SELECT bike_no, ', @sql, '
from bike
where repair_date >= ''', @startdate, '''
and repair_date <= ''', @enddate, '''
group by bike_no');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SQL Fiddle with Demo を参照してください。どちらのクエリでも上記のデータのテーブルが生成されます。