2016-05-03 45 views
1

數據MySQL交叉表/數據透視聚合。刪除基於列數其他表

我有以下格式的一組數據:

CAR_INVENTORY TABLE 
CAR_ID MAKE_MODEL  COLOR YEAR 
1  Ford Fusion  Black 2015 
2  Tesla Model S White 2014 
3  Acura ILX  Blue 2013 
4  Ford Fusion  Black 2013 
5  Toyota Corolla Blue 2014 
6  Ford Fusion  Blue 2013 
7  Toyota Corolla Blue 2012 
8  Acura ILX  Black 2015 
9  Ford Focus  Blue 2012 
10  Ford Fusion  White 2013 
11  Acura ILX  Black 2012 
12  Toyota Corolla Black 2015 
13  Toyota Corolla Blue 2014 
14  Ford Focus  White 2015 
15  Tesla Model S Red  2015 
16  Acura TLX  White 2014 
17  Toyota Corolla Blue 2014 
18  Ford Focus  Black 2013 

INVENTORY_LOG TABLE 
LOG_ID CAR_ID NOTE 
1  7  Issue with Fuel Guage 
2  3  Sweet Ride 
3  16  Zippy 
4  14  Issue with transmission 
5  3  Fun to Drive 
6  2  *NULL* 
7  8  *NULL* 
8  10  Economic 
9  15  WOW 
10  9  Good Fuel Economy 
11  16  Minor issue with Shifting 
12  7  Issue with Airbag 
13  17  Great Mileage 
14  1  Nice Tech 
15  13  *NULL* 
16  11  Trunk is small 
17  12  *NULL* 
18  2  Very Speedy 
19  7  Good Mileage 
20  10  Roomy 
21  4  *NULL* 
22  6  Nice Tech Package 
23  5  Good Economy 
24  18  Cool 

我知道這不是完全正常化。我們假設我不能搞亂數據。

car_inventory表中每輛車都有一排庫存。 inventory_log表對於car_inventory中列出的每輛車至少有一個條目,因此每輛車可能有許多日誌條目。 inventory_log中的條目可以爲null。

我到目前爲止

如果汽車有它的詞「問題」日誌完成,它需要進行標註。我已經想通的那部分:

SELECT 
    ci.car_id, 
    CONCAT(ci.color, " ", ci.make_model) as car, 
    SUM(IF (LOWER(il.note) LIKE '%issue%', TRUE, FALSE)) AS issue 
FROM car_inventory ci 
    LEFT JOIN inventory_log il USING (car_id) 
GROUP BY ci.car_id 
ORDER BY ci.car_id; 

這yealds:

car_id car      issue 
1  Black Ford Fusion  0 
2  White Tesla Model S  0 
3  Blue Acura ILX   0 
4  Black Ford Fusion  0 
5  Blue Toyota Corolla  0 
6  Blue Ford Fusion  0 
7  Blue Toyota Corolla  2 
8  Black Acura ILX   0 
9  Blue Ford Focus   0 
10  White Ford Fusion  0 
11  Black Acura ILX   0 
12  Black Toyota Corolla 0 
13  Blue Toyota Corolla  0 
14  White Ford Focus  1 
15  Red Tesla Model S  0 
16  White Acura TLX   1 
17  Blue Toyota Corolla  0 
18  Black Ford Focus  0 

這給非零結果與問題的任何汽車。


我需要做的下一件事是通過他們的顏色,超過一定的年份計數所有。假設我們只對黑色,白色和藍色感興趣,我們只有福特,謳歌,豐田和特斯拉(我知道我可以使用準備好的語句來實現這種動態)。明白了一箇中袋過:

SELECT 
    CASE 
     WHEN ci.make_model LIKE "Acura%" THEN "Acura" 
     WHEN ci.make_model LIKE "Ford%" THEN "Ford" 
     WHEN ci.make_model LIKE "Toyota%" THEN "Toyota" 
     WHEN ci.make_model LIKE "Tesla%" THEN "Tesla" 
    END AS Make, 
    SUM(CASE WHEN ci.color = "Black" THEN 1 ELSE 0 END) as Black, 
    SUM(CASE WHEN ci.color = "Blue" THEN 1 ELSE 0 END) as Blue, 
    SUM(CASE WHEN ci.color = "White" THEN 1 ELSE 0 END) as White 
FROM car_inventory ci 
    LEFT JOIN inventory_log il USING (car_id) 
WHERE 
    ci.year > 2012 
GROUP BY Make 
ORDER BY Make; 

這給了我:

Make Black Blue White 
Acura 1  1  1 
Ford 3  1  2 
Tesla 0  0  1 
Toyota 1  3  0 

在做car_inventory表的快速計數,有14輛汽車於2012年更新的,那是黑色,藍色或白色。

的問題

這裏就是我有麻煩:

我試圖做的是將二者結合起來。我需要根據顏色來計算所有顏色,哪裏沒有問題。

這裏的結果集,我試圖讓:

DESIRED RESULT 
MAKE   Black Blue White 
Acura   1  1  0 
Ford   3  1  1 
Tesla   0  0  1 
Toyota   1  2  0 

以下三個車中刪除:

car_id car      issues 
7  Blue Toyota Corolla  2 
14  White Ford Focus  1 
16  White Acura TLX   1 

我嘗試添加AND SUM(IF (LOWER(il.note) LIKE '%issue%', TRUE, FALSE)) = 0 WHERE子句。這會導致mysql錯誤1111「組功能的無效使用」。我也試過HAVING SUM(IF (LOWER(il.note) LIKE '%issue%', TRUE, FALSE)) != 0。它不正確的結果,只顯示特斯拉和豐田的行。

問題

如何創建MySQL中的交叉表查詢,使得汽車(從car_inventory)與在他們所說的「問題」的日誌條目(來自inventory_log)不計?

回答

1
SELECT 
    CASE 
     WHEN ci.make_model LIKE "Acura%" THEN "Acura" 
     WHEN ci.make_model LIKE "Ford%" THEN "Ford" 
     WHEN ci.make_model LIKE "Toyota%" THEN "Toyota" 
     WHEN ci.make_model LIKE "Tesla%" THEN "Tesla" 
    END AS Make, 
    SUM(CASE WHEN ci.color = "Black" THEN 1 ELSE 0 END) as Black, 
    SUM(CASE WHEN ci.color = "Blue" THEN 1 ELSE 0 END) as Blue, 
    SUM(CASE WHEN ci.color = "White" THEN 1 ELSE 0 END) as White 
FROM car_inventory ci 
WHERE 
    (ci.year > 2012) and 
    (ci.car_id not in (select distinct il.car_id from inventory_log il where il.note like '%issue%')) 
GROUP BY Make 
ORDER BY Make; 
+0

將子查詢移動到where子句似乎更快。謝謝。 – mcmurphy

0

所以我想出如何使用子查詢做到這一點:

SELECT 
    CASE 
     WHEN ci.make_model LIKE "Acura%" THEN "Acura" 
     WHEN ci.make_model LIKE "Ford%" THEN "Ford" 
     WHEN ci.make_model LIKE "Toyota%" THEN "Toyota" 
     WHEN ci.make_model LIKE "Tesla%" THEN "Tesla" 
    END AS Make, 
    SUM(CASE WHEN ci.color = "Black" THEN 1 ELSE 0 END) as Black, 
    SUM(CASE WHEN ci.color = "Blue" THEN 1 ELSE 0 END) as Blue, 
    SUM(CASE WHEN ci.color = "White" THEN 1 ELSE 0 END) as White 
FROM (

     SELECT 
      ci2.car_id, 
      ci2.make_model, 
      ci2.color 
     FROM car_inventory ci2 
      LEFT JOIN inventory_log il2 USING (car_id) 
     WHERE 
      ci2.year > 2012 
     GROUP BY ci2.car_id 
     HAVING SUM(IF (LOWER(il2.note) LIKE '%issue%', TRUE, FALSE)) = 0 

) as ci 
GROUP BY Make 
ORDER BY Make; 

這給了我:

Make Black Blue White 
Acura 1  1  0 
Ford 3  1  1 
Tesla 0  0  1 
Toyota 1  3  0 

我不會將此標記爲接受的答案,因爲我很確定沒有子查詢有更好,更高效的方法來做到這一點。