2016-12-22 6 views
0

私は仕事場に小さな報告システムを組み込むように求められました。私たちは、ユーザーが情報をコミットするデータベース、つまりさまざまなイベントの開始時間と終了時間を持っています。 DBの別のテーブルによって識別されるテーブルのデータに結合する

関連するテーブル: enter image description here

あなたが見ることができるように、イベントはサブカテゴリがあり、各サブカテゴリはカテゴリに属します。

カテゴリのイベントが所定の期間内に発生した合計時間を表すグラフを作成するように求められました。

したがって、たとえば:

Category Name | Total time 
************************** 
Balloons  | 12h 
Chalk   | 5.5h 

私は、結合文のうち、合計を取得して苦労しています。ご覧のように、時間の総量をさまざまなカテゴリにマップするには、どのカテゴリに属する​​サブカテゴリを最初に識別し、それに応じてイベントを整理する必要があります。

私は、ストアドプロシージャを作成するか、一時テーブルを作成するのではなく、1つのクエリでこれを記述するのは致命的です。私はそれがジョインだけで完了できると確信していましたが、そうではないようです。 私は、どんな解決策にでも完全に対応しています。

1つの要件。

SELECT 
    event_categories.name, 
    SUM(TIMESTAMPDIFF(MINUTE, 
     events.start, 
     events.stop)/60) AS timeLost 
FROM 
    events 
     LEFT JOIN 
    event_subcategories ON event_subcategories.id = events.subcategory 
     RIGHT JOIN 
    event_categories ON event_categories.id = event_subcategories.id 
WHERE 
    events.date BETWEEN '2016-12-01' AND '2016-12-22' 
     AND events.bed = 1 
GROUP BY event_categories.id; 

それほとんど作品:指定したカテゴリはイベントを持っていない場合、それはまだのみ0

これがデフォルト値で、結果に表示されるべきことは、私がこれまで持っているものです関連する時間が失われたカテゴリのリストを生成する。すべてのカテゴリは表示されず、関連するイベントのカテゴリのみが表示されます。

+0

「LEFT JOIN」ではなく「RIGHT JOIN」を使用してください。 – Barmar

+0

@Barmar私は(event_categoriesテーブルで)しました。私は両方の結合でそれを試しました。結果は同じです。 –

+0

LEFT JOINでは、最初のテーブルがマスターテーブルで、2番目のテーブルが子テーブルです。 'RIGHT JOIN'ではそれは逆です。 – Barmar

答えて

1

ジョインを行う方法を変更します。メインテーブルはevent_categoriesである必要があります。すべてのカテゴリにサブカテゴリがあると仮定すると、INNER JOINevent_subcategoriesを使用できます。最後にLEFT JOINeventsを使用してください。一部のサブカテゴリにはイベントがない可能性があります。

あなたはまた、間違った列にevent_categoriesevent_subcategoriesを参加させていました。 event_subcategory.idではなく、event_subcategories.categoryにする必要があります。

LEFT JOINを実行すると、子テーブルの条件は、の句になります。WHEREではなくなります。イベントのないカテゴリではevent列すべてに対してNULLが得られるため、条件はそれらの行に対して決して成功することはなく、INNER JOINのようにフィルタリングされます。

SELECT 
    c.name, 
    SUM(TIMESTAMPDIFF(MINUTE, 
     e.start, 
     e.stop)/60) AS timeLost 
FROM event_categories AS c 
JOIN event_subcategories AS s ON s.category = c.id 
LEFT JOIN events AS e ON e.subcategory = s.id 
    AND e.date BETWEEN '2016-12-01' AND '2016-12-22' 
    AND e.bed = 1 
GROUP BY c.id; 
+0

私はそれを試してみましたが、それは動作しますが、 'WHERE events.date BETWEEN '2016-12-01' AND '2016-12-22' AND events.bed = 1'を追加すると、カテゴリは表示されませんイベントはありません... –

+0

基本的に、特定の日付範囲に絞り込むためにはクエリが必要です。日付はイベントテーブルにあります。 –

+0

'LEFT JOIN'テーブルの条件は、' WHERE'節ではなく 'ON'節に入れる必要があります。 – Barmar

関連する問題