2013-03-08 35 views
1

Example of Data查找統計數據,使用PHP和MySQL

在這個例子中數據的每個組合(不常見的),我想對每個組合的平均煙柱。當事情變得複雜時。

這是不是簡單查找(男性,30-40,美國),(男性,30-40,ca),(男性,30-40,th)等的平均(煙)。 (男,30-40,(美國,英國)),(男,30-40,(美國,英國,英國))我想要的是一些變量可以在單個查詢中使用超過1次, ),,(男,30-40,(我們,英國,th,ca))等等。

任何簡單,有效的方法呢?

+0

你不能只寫一個報告生成器,用戶可以選擇的條件語句,然後你從tbldetails構建成一個where子句所以你再這樣做'選擇AVG(煙),其中性別=」男'AND(年齡= '30 -40'或年齡= '50 -60')AND Country'('us','ca','th')' – Dave 2013-03-08 16:16:20

+0

我想要所有可能的組合。數據可能會變得比這更大。也許30萬人在100多個新的不同國家和10個年齡段。腳本和查詢需要是動態的。 – 2013-03-08 16:18:45

+0

如果你想自動化它,你必須恢復所有可能的解決方案,或者將它們歸一化到關鍵表中,並將這些錶鏈接到數據表中的條目,或者首先需要多次循環訪問單個表以獲取所有的分類如性別,年齡等 – Dave 2013-03-08 16:49:53

回答

0

如果可以的話,我會建議標準化您的數據,以便使用內置函數更容易實現您的目標。這可能會比提出一種能夠以現在的方式工作的查詢更快。

+0

請解釋更多。數據庫正常化後,你有任何關於如何編寫php和/或mysql查詢的建議嗎? – 2013-03-08 16:12:46

0

你可以得到這樣的每一個組合:

SELECT q.sort_key,avg(s.id) 
FROM foo AS s 
JOIN 
    (SELECT GROUP_CONCAT(f0.bar) AS sort_key 
    FROM foo AS f1 
    JOIN foo AS f2 ON f1.bar<=f2.bar 
    JOIN foo AS f3 ON f2.bar<=f3.bar 
    JOIN foo AS f0 ON f0.bar=f1.bar OR f0.bar=f2.bar OR f0.bar=f3.bar 
    GROUP BY f1.bar,f2.bar,f3.bar) AS q ON find_in_set(s.bar,q.sort_key) 
GROUP BY q.sort_key; 

http://sqlfiddle.com/#!2/1fdbf/32

由於MySQL不支持遞歸CTE你將不得不使用盡可能多的表,因爲有可能是參數的不同勢值( 2爲性別,4(?)爲國家等)。一旦你有所有參數的可能組合,做一個笛卡爾加入他們並由他們分組。在PHP中,你只需要將一個排序鍵(男,女)改爲ALL GENDERS。

EDIT2: 修正了模糊,可能連接可能會更好,但它仍然可以工作。

0

一個簡單的方法是連接的獨立/預測變量作爲字符串在單獨的列中,則基於所述字符串

ALTER TABLE `statistical_data` ADD `variables_string` VARCHAR(255) NOT NULL 

UPDATE `statistical_data` SET`variables_string` = CONCAT(`gender`, `age`, `country`) 

SELECT `gender`, `age`, `country`, AVG(smoke) FROM `statistical_data`GROUP BY `variables_string` 

A的GROUP BY WHERE可以使用條款得到AVG(煙) ,例如,要獲得所有組合的平均值,其中性別是男性,但是您必須將所有組合的煙霧總數(1的數量)除以組合的頻率(n),因爲您無法取平均值的平均值。

SELECT (SUM(smoke_sum)/SUM(smoke_count)) FROM (SELECT `gender`, `age`, `country`, SUM(smoke) AS smoke_sum, COUNT(smoke) AS smoke_count FROM`statistical_data` WHERE `gender` = 'male' GROUP BY variables_string) AS t2 
+0

你不需要一個新的專欄,你可以做'GROUP BY性別,年齡,國家'和結果是完全一樣的。這不會給你所有可能的組合。你也選擇了一個你沒有分組的名字(*),所以你的結果將是不可預測的。 – 2013-03-08 21:00:52

+0

我在考慮一個單獨的列將在更大的數據上表現更好。此外,結果不會是不可預知的,因爲分析中可能不需要name變量,所以拋出的隨機名可以忽略。是的,這會給出所有可能的組合,因爲性別,年齡和國家的每個組合都會有一個唯一的字符串。 – pudspop 2013-03-08 21:49:37

+0

它會給你30-40歲男性的平均值,但不會給你男性,所有年齡段,所有國家的結果。如果你知道名稱將是semirandom你不應該選擇它,它只是垃圾。 – 2013-03-08 21:59:43