2011-05-03 58 views
1

我想顯示數據逐年重新排列,其中一種可能的解決方案是使用視圖並從中選擇。數據矩陣是一樣的東西(當然這是一個虛構的演示數據集):從視圖中選擇MySQL多維

USA 2005 22 156 
CAN 2005 14 101 
MEX 2005 5 32 
USA 2006 24 160 
CAN 2006 16 103 
USA 2007 26 163 
MEX 2007 8 35 

的SQL代碼來創建和填充表:

DROP TABLE IF EXISTS `tab1`;<br> 
CREATE TABLE `tab1` (<br> 
    `id1` int(4) unsigned NOT NULL AUTO_INCREMENT, 
    `iso3` char(3) NOT NULL, 
    `year` int(4) unsigned NOT NULL, 
    `aaa` int(10) DEFAULT NULL, 
    `bbb` int(10) DEFAULT NULL, 
    PRIMARY KEY (`id1`) 
) 


INSERT INTO `tab1` VALUES 
('1', 'USA', '2005', '22', '156'), 
('2', 'CAN', '2005', '14', '101'), 
('3', 'MEX', '2005', '5', '32'), 
('4', 'USA', '2006', '24', '160'), 
('5', 'CAN', '2006', '16', '103'), 
('6', 'USA', '2007', '26', '163'), 
('7', 'MEX', '2007', '8', '35'); 
COMMIT; 

現在我想獲得的參數「AAA」一個二維表是這樣的:

country 2005 2006 2007 
USA  22 24 26 
CAN  14 16   
MEX  5 8 

但是下面的SQL代碼省略所有缺少數據的線,無論是一個單一的價值,我只得到一個行

USA 22 24 26 

的SQL代碼:

SELECT view2005.Country, view2005.2005, view2006.2006, view2007.2007 
FROM view2005, view2006, view2007 
WHERE view2005.country = view2006.country 
AND view2005.country = view2007.country 

任何想法如何做到這一點,包括缺失數據線?提前致謝。

回答

0

最好使用JOIN而不是隱式加入WHERE。額外的優點是你可以將它轉換爲LEFT JOIN,因此2005年的數據沒有2006相關行(並且不匹配)仍然會顯示。

使用Galz的解決方案或搜索正確建議如何創建PIVOT查詢。


一個這樣的邏輯來創建一個支點查詢將是:

SELECT iso3 AS Country 
     , SUM(IF(year=2005, aaa, 0)) AS 2005 
     , SUM(IF(year=2006, aaa, 0)) AS 2006 
     , SUM(IF(year=2007, aaa, 0)) AS 2007 
FROM tab1 AS t 
GROUP BY iso3 

如果有幾年沒有任何數據,您將在該列得到NULL
可以使用COALESCE()功能,如果你想0中顯示,而不是NULL

SELECT iso3 AS Country 
     , COALESCE(SUM(IF(year=2004, aaa, 0)) , 0) AS "2004" 
     , COALESCE(SUM(IF(year=2005, aaa, 0)) , 0) AS "2005" 
     , COALESCE(SUM(IF(year=2006, aaa, 0)) , 0) AS "2006" 
     , COALESCE(SUM(IF(year=2007, aaa, 0)) , 0) AS "2007" 
FROM tab1 AS t 
GROUP BY iso3 
+0

那些沒有2005年數據的國家呢? – Galz 2011-05-03 16:00:23

+0

是的,這不是一個好的嘗試,刪除它。發佈新的一個。 – 2011-05-03 16:19:59

2

使用左聯接和視圖(或表,或內選擇如下圖所示),其中有所有不同的國家:

SELECT c.country, view2005.2005, view2006.2006, view2007.2007 
FROM (SELECT DISTINCT country FROM tab1) as c 
LEFT JOIN view2005 ON view2005.country = c.country 
LEFT JOIN view2006 ON view2006.country = c.country 
LEFT JOIN view2007 ON view2007.country = c.country 
GROUP BY c.country 

編輯:

在更普遍的情況下,你問這裏是創建一個樞軸這張表,這是一個常見的問題,有共同的解決方案。這裏是一個很好的「如何」:http://www.artfulsoftware.com/infotree/queries.php?&bw=1339#78

0

謝謝Galz的樞紐鏈接,謝謝ypercube的SQL。它在將年份放入引號以使其成爲CHAR之後起作用。

我被我是否添加一行在全部或沒有值的行出來的年,所以我加入

INSERT INTO `tab1` VALUES 
('7', 'ATA', '2004', '', '') 

的結果是,我得到了一個範圍怎麼辦的問題進一步感興趣NULL和INT零值的混合。這是不好的,因爲零是一個有效的數字和合法的數據。所以我修改了查詢以獲得我需要的結果:

SELECT iso3 AS countryб 
     SUM(IF(year=2004, aaa, NULL)) AS "2004", 
     SUM(IF(year=2005, aaa, NULL)) AS "2005", 
     SUM(IF(year=2006, aaa, NULL)) AS "2006", 
     SUM(IF(year=2007, aaa, NULL)) AS "2007" 
FROM tab1 
GROUP BY iso3 
+0

如果你想顯示'0'而不是'NULL',你可以使用'COALESCE()'函數。 – 2011-05-04 15:04:44