2017-10-17 19 views
0

私は約5週間今作業しているプロジェクトで問題を抱えています。途中で様々なスタックオーバーフローポストを作成しましたが、私はほとんど最終的なハードルです。ダイナミックピボットMYSQL不完全なSQL

私は週ごとの合計検索で重複したデータの問題を抱えていましたが、私はそれを理解したようですが、私の声明は完了していません。 REf: Weekly Sum Dynamic Pivot MYSQL

ここにはデータがあります。あなたが最後の文を見ることができるように はhttp://sqlfiddle.com/#!9/a3610

$period = 'YEARWEEK'; 


    $sql = " 
    SELECT 
     GROUP_CONCAT(DISTINCT 
     CONCAT(
      'SUM(CASE WHEN (".$period."(date)) = ', 
      (".$period."(date)), 
      ' THEN AMOUNT else 0 END) AS `', 
      (".$period."(date)), 
      '`' 
     ) 
     ORDER BY date ASC) AS `pivot_columns` 
    FROM record_offering 
    WHERE date BETWEEN ? AND ? 
    ORDER BY date ASC 
"; 

$stmt = $pdo->prepare($sql); 
$date_from = '2017-01-01'; 
$date_to = '2017-10-01'; 
$stmt->execute([$date_from, $date_to]); 
$row = $stmt->fetch(); 
$stmt->closeCursor(); 
$pivot_columns = $row['pivot_columns']; 

$sql = " 
    SELECT title AS `Service`, {$pivot_columns} 
    from record_offering t1 
    join setting_service ON t1.service_id = setting_service.id 
    WHERE t1.date BETWEEN ? AND ? 
    GROUP BY title asc WITH ROLLUP 
"; 

$stmt = $pdo->prepare($sql); 
$stmt->execute([$date_from, $date_to]); 
$results = $stmt->fetchAll(); 
$stmt->closeCursor(); 

不完全です:私はさまざまな方法でクエリを脱出しようとしているが、クエリのいずれかが完了し、私のデータが重複しているか、そうでない

SELECT title AS `Service`, SUM(CASE WHEN (YEARWEEK(date)) = 201635 THEN AMOUNT else 0 END) AS `201635`, 
SUM(CASE WHEN (YEARWEEK(date)) = 201703 THEN AMOUNT else 0 END) AS `201703`, 
SUM(CASE WHEN (YEARWEEK(date)) = 201709 THEN AMOUNT else 0 END) AS `201709`, 
SUM(CASE WHEN (YEARWEEK(date)) = 201713 THEN AMOUNT else 0 END) AS `201713`, 
SUM(CASE WHEN (YEARWEEK(date)) = 201715 THEN AMOUNT else 0 END) AS `201715`, 
SUM(CASE WHEN (YEARWEEK(date)) = 201717 THEN AMOUNT else 0 END) AS `201717`, 
SUM(CASE WHEN (YEARWEEK(date)) = 201718 THEN AMOUNT else 0 END) AS `201718`, 
SUM(CASE WHEN (YEARWEEK(date)) = 201722 THEN AMOUNT else 0 END) AS `201722`, 
SUM(CASE WHEN (YEARWEEK(date)) = 201723 THEN AMOUNT else 0 END) AS `201723`, 
SUM(CASE WHEN (YEARWEEK(date)) = 201725 THEN AMOUNT else 0 END) AS `201725`, 
SUM(CASE WHEN (YEARWEEK(date)) = 201726 THEN AMOUNT else 0 END) AS `201726`, 
SUM(CASE WHEN (YEARWEEK(date)) = 201735 THEN AMOUNT else 0 END) AS `201735`, 
SUM(CASE WHEN (YEARWEEK(date)) = 201736 THEN AMOUNT else 0 END) AS `201736`, 
SUM(CASE WHEN (YEARWEEK(date)) = 201 
from record_offering t1 
join setting_service ON t1.service_id = setting_service.id 
WHERE t1.`date` BETWEEN ? AND ? 
GROUP BY title asc WITH ROLLUP 

まったくコンパイルしないでください。

+1

アプリケーションコードのデータ表示に関する問題を真剣に検討してください。このクエリを大幅に簡略化します。私の見解では、あなたの現在の戦略は完全に前面に戻っています – Strawberry

+0

私の最初の試行は基本的な和とグループクエリでしたが、私はPHPを使って変換しましたが、過去のデータを正確に集計しませんでした。私はその後ピボットを試すようにアドバイスされました –

+0

プレゼンテーションレイヤーコードが利用可能な場合、この方法でピボットデータのポイントを見ることができません。 – Strawberry

答えて

2

GROUP_CONCATには1024バイトの制限があります。

GROUP_CONCATクエリの前に使用

SET SESSION group_concat_max_len = @@max_allowed_packet

+0

これについてのアイデアはありませんでしたが、現在のところこのプロジェクトは共有ホスティングで実行されていますが、私はこれに正しいルートアクセスが必要だと思いますか? –

+0

@Enoch SいいえSUPER特権なしで、またはルートアクセスなしでこの設定を使用することができます –

0

私の考え方では、この問題(またはそれに非常に似ています)は、この問題に必要なすべてのSQLです。 すべては、プレゼンテーションレイヤーで処理できる必要があります。

SELECT YEARWEEK(x.date) yw 
    , x.title 
    , COALESCE(SUM(y.amount),0) total 
    FROM setting_service x 
    LEFT 
    JOIN record_offering y 
    ON y.service_id = x.id 
GROUP 
    BY yw 
    , x.id; 
+0

私の最初の努力はあなたが言った通りです。これは私がSAに投稿した質問です:https://stackoverflow.com/questions/45267138/datatables-dates-at-the-top-and-data-cells-going-from-left-to-right –

+0

私ははるかに良いアプローチのように思える。唯一の問題は「ROLLUP」です.JavaScriptを使って簡単に行うことができます。 – Strawberry

+0

が実行されている可能性がありますが、データを正しく集約できないという問題がありました。 http://www.phpwin.org/s/0xFWpFはフィドルです。あなたがtheadとtbodyの間隔を+1日に変更した場合、データは正しいですが、+1週では、最初のデータが5だったはずです –