2012-03-15 9 views
0

複数のテーブルを選択して空のカラムを持つようにしようとしています。例えば 私のテーブル:SQLが複数のテーブルを結合したままになりました

calendar: //filled with dates from 2011-01-01 to 2015-12-31 
+-----------+ 
| datefield | 
+-----------+ 
| 2012-1-1 | 
| 2012-1-2 | 
| ...  | 
| 2012-2-3 | 
| 2012-2-4 | 
+-----------+ 

car: 
+--------+---------+ 
| car_id | name | 
+--------+---------+ 
|  1 | Ford | 
|  2 | Peugeot | 
|  3 | Fiat | 
+--------+---------+ 

carsales: 
+-------------+-----------+--------+-------------+ 
| car_sale_id | sell_time | car_id | customer_id | 
+-------------+-----------+--------+-------------+ 
|   1 | 2012-1-2 |  1 |   1 | 
|   1 | 2012-1-2 |  2 |   1 | 
|   2 | 2012-1-3 |  3 |   2 | 
+-------------+-----------+--------+-------------+ 

customer: 
+-------------+---------+ 
| customer_id | country | 
+-------------+---------+ 
|   1 | NL  | 
|   2 | EN  | 
+-------------+---------+ 

は今、私は車名で「NL」から顧客によって販売されている車の量のリストが欲しい、そして2012年1月1日と2012年2月1日の間(で週間)。日付は常に存在する必要があります。例えば

SELECT WEEKOFYEAR(calendar.datefield) as 'Week', car.name, COUNT(carsales.car_id) 
FROM car, customer, calendar 
LEFT JOIN carsales ON DATE(calendar.datefield) = DATE(carsales.sell_time) 
WHERE calendar.datefield > '2012-01-01' AND calendar.datefield < '2012-02-01' 
AND car.id = carsales.car_id 
AND customer.country = 'NL' 
AND customer.customer_id = carsales.customer_id 
GROUP BY 'Week', car.name 
ORDER BY 'Week', car.name; 

は、私が何をしないのです:

+----------+----------+-------+ 
| Week | Car name | Sales | 
+----------+----------+-------+ 
| 1  | Ford  |  0 | 
| 1  | Peugeot |  0 | 
| 1  | Fiat  |  0 | 
| 2  | Ford  |  1 | 
| 2  | Peugeot |  1 | 
| 2  | Fiat  |  0 | 
| 3  | Ford  |  0 | 
| 3  | Peugeot |  0 | 
| 3  | Fiat  |  0 | 
| etc  | ...  | ... | 
+----------+----------+-------+ 

私はこの思い付きましたか?

+0

カレンダーテーブルのポイントは何ですか? –

+2

'carsales.customer_id = customer.id'のような条件がありません。暗黙的な結合と明示的な結合を組み合わせることもあります。テーブルを結合するには 'JOIN'キーワードを使います。 –

+0

@ypercube、それは答えでなければならない –

答えて

2

。これは、あなたのカレンダーテーブルの内容を正確に知っていないことに基づいています...それは毎日を表していますか?または特定の週のちょうど最初の日。もしそうなら、少し調整する必要があります。その後、車種ごとにデカルト結果を得て、毎週各車が常に表示されるようにします。最後に、私たちはLEFT JOIN(週や車を緩めないため)を販売データに残すことができます。特定の国の資格に基づいて顧客にもそれを参加させてください。

SUM(IF())は、自動車販売、顧客、およびお客様が「NL」国にいるISのみを確実にカウントするためのものです。それ以外の売上は無視されます。

SELECT 
     AllWeeksAllCars.WeekNumber, 
     AllWeeksAllCars.Name, 
     SUM(IF(Customer.Customer_ID > 0, 1, 0)) as CarSales 
    FROM 
     (select AllWeeks.*, 
       Car.car_id, 
       Car.Name 
      from 
       (select 
         WEEKOFYEAR(Calendar.DateField) as WeekNumber, 
         MIN(Calendar.DateField) as FirstDate, 
         MAX(Calendar.DateField) as LastDate 
        from 
         Calendar 
        where 
          Calendar.dateField > '2012-01-01' 
         AND Calendar.dateField < '2012-01-01' 
        group by 
         `WeekNumber`) AllWeeks, 
       car 
      order by 
       AllWeeks.WeekNumber, 
       Car.Name ) AllWeeksAllCars 

     LEFT JOIN CarSales 
      on CarSales.Sell_Time between AllWeeksAllCars.FirstDate and AllWeeksAllCars.LastDate 
      AND CarSales.Car_ID = AllWeeksAllCars.Car_ID 

      LEFT JOIN Customer 
       on CarSales.Customer_ID = Customer.Customer_ID 
       AND Customer.Country = 'NL' 
    GROUP BY 
     AllWeeksAllCars.WeekNumber, 
     AllWeeksAllCars.Name 
+0

これはトリックでした。マイナーなメモ、daterangeが年を越える場合、週番号は台無しです。これを修正するために年の列も追加します。 – RvdK

1

あなたが探している情報はcarsalesテーブルにあります。私はそこから始めて、インナーカーとカレンダーに参加しました。あなたは正しい方法で考えている

+0

SQLステートメントでどのようにこれを行うのですか?ブラケットなど? – RvdK

2

...あなたが最初にあなたが期待している時間内にすべての可能な「週間」を示し、結果セットを作成する必要が

SELECT WEEKOFYEAR(carsales.sell_time) as 'Week', car.name, COUNT(carsales.car_sale_id) 
FROM carsales 
LEFT JOIN car ON car.id=carsales.car_id 
LEFT JOIN customer ON customer.customer_id=carsales.customer_id 
WHERE carsales.sell_time BETWEEN '2012-01-01' AND '2012-02-01' 
AND customer.country = 'NL' 
GROUP BY 'Week', car.name 
ORDER BY 'Week', car.name; 
+0

これを使って私は戻ってくる:(1、Ford、32)と(1、プジョー、32)。だから私は週2 t/mの値を逃している56. – RvdK

+0

ああ、申し訳ありません。 「WHERE calendar.datefield BETWEEN」2012-01-01「AND」2012-02-01 '「WHERE carsales.sell_time BETWEEN」2012-01-01「AND」2012-02-01「 –

+0

はい金額は修正されますが、欠落した週は修正されません。 – RvdK

関連する問題