2013-10-06 44 views
2

我有模式三個表如下:複雜的SQL查詢建議,請

表:應用

| ID (bigint) | USERID (Bigint)|  START_TIME (datetime) | 
------------------------------------------------------------- 
| 1   |  13  |   2013-05-03 04:42:55 | 
| 2   |  13  |   2013-05-12 06:22:45 | 
| 3   |  13  |   2013-06-12 08:44:24 |  
| 4   |  13  |   2013-06-24 04:20:56 |  
| 5   |  13  |   2013-06-26 08:20:26 |  
| 6   |  13  |   2013-09-12 05:48:27 | 

表:主機

| ID (bigint) | APPID (Bigint)|   DEVICE_ID (Bigint) | 
------------------------------------------------------------- 
| 1   |  1  |       1 | 
| 2   |  2  |       1 | 
| 3   |  1  |       1 |  
| 4   |  3  |       3 |  
| 5   |  1  |       4 |  
| 6   |  2  |       3 | 

表:使用

| ID (bigint) | APPID (Bigint)|    HOSTID (Bigint) | Factor (varchar) | 
------------------------------------------------------------------------------------- 
| 1   |  1  |       1 |    Low  | 
| 2   |  1  |       3 |    High | 
| 3   |  2  |       2 |    Low  | 
| 4   |  3  |       4 |    Medium | 
| 5   |  1  |       5 |    Low  | 
| 6   |  2  |       2 |    Medium | 

現在,如果把用戶ID是,我想錶行的行計數每個月(所有應用程序)的每個「因子」月明智的最後6個月

如果DEVICE_ID在一個月內出現多次(基於START_TIME,基於加入應用程序和主機),則僅計算最新的使用行(基於應用程序,主機和用法的組合)。該查詢用於上述示例的

實施例輸出應該是:(用於輸入用戶ID = 13)

| MONTH  | USAGE_COUNT |    FACTOR  | 
------------------------------------------------------------- 
| 5   |  0  |     High  | 
| 6   |  0  |     High  | 
| 7   |  0  |     High  | 
| 8   |  0  |     High  |  
| 9   |  0  |     High  |  
| 10   |  0  |     High  | 
| 5   |  2  |     Low   | 
| 6   |  0  |     Low   | 
| 7   |  0  |     Low   | 
| 8   |  0  |     Low   |  
| 9   |  0  |     Low   |  
| 10   |  0  |     Low   | 
| 5   |  1  |     Medium  | 
| 6   |  1  |     Medium  | 
| 7   |  0  |     Medium  | 
| 8   |  0  |     Medium  |  
| 9   |  0  |     Medium  |  
| 10   |  0  |     Medium  | 

這是如何計算的?

  1. 單月2013年5月(05-2013),還有從表應用兩個應用程序
  2. 在臺主機,這些應用程序與DEVICE_ID的1,1,1,4,3
  3. 對於相關本月(05-2013)爲device_id = 1,start_time的最新值爲:2013-05-12 06:22:45(來自桌面主機,應用程序),所以在表中使用,查找appid = 2的組合,hostid = 2,其中有兩行,一個因子爲Low和其他介質,
  4. 對於本月(05-2013)的device_id = 4,通過遵循相同的過程,我們得到一個條目,即0低
  5. 類似地,計算所有的值。

要獲得通過查詢最近6個月我試圖用下面的獲得它:

SELECT MONTH(DATE_ADD(NOW(), INTERVAL aInt MONTH)) AS aMonth 
    FROM 
    (
     SELECT 0 AS aInt UNION SELECT -1 UNION SELECT -2 UNION SELECT -3 UNION SELECT -4 UNION SELECT -5 
    ) 

請檢查sqlfiddle:http://sqlfiddle.com/#!2/55fc2

+0

你可能需要編輯澄清這個問題。我的答案和@ ubik404都可以是有效的,具體取決於你想要的行爲。 – Dan

+0

@丹我只能看到你的答案。我正在測試它。謝謝。 – user2818666

回答

1

因爲你正在做的計算過程中,同樣的連接多次,我開始創建一個視圖。

CREATE VIEW `app_host_usage` 
AS 
SELECT a.id "appid", h.id "hostid", u.id "usageid", 
     a.userid, a.start_time, h.device_id, u.factor 
    FROM apps a 
    LEFT OUTER JOIN hosts h ON h.appid = a.id 
    LEFT OUTER JOIN `usage` u ON u.appid = a.id AND u.hostid = h.id 
    WHERE a.start_time > DATE_ADD(NOW(), INTERVAL -7 MONTH) 

WHERE條件是存在的,因爲我做的,你不希望2005年7月和2006年7月在同一數組合在一起的假設。

有了這種看法,查詢變得

SELECT months.Month, COUNT(DISTINCT device_id), factors.factor 
FROM 
    (
    -- Get the last six months 
    SELECT (MONTH(NOW()) + aInt + 11) % 12 + 1 "Month" FROM 
     (SELECT 0 AS aInt UNION SELECT -1 UNION SELECT -2 UNION SELECT -3 UNION SELECT -4 UNION SELECT -5) LastSix 
) months 
    JOIN 
    ( 
    -- Get all known factors 
    SELECT DISTINCT factor FROM `usage` 
) factors 
    LEFT OUTER JOIN 
    (
    -- Get factors for each device... 
    SELECT 
      MONTH(start_time) "Month", 
      device_id, 
      factor 
     FROM app_host_usage a 
     WHERE userid=13 
     AND start_time IN (
      -- ...where the corresponding usage row is connected 
      -- to an app row with the highest start time of the 
      -- month for that device. 
      SELECT MAX(start_time) 
      FROM app_host_usage a2 
      WHERE a2.device_id = a.device_id 
      GROUP BY MONTH(start_time) 
     ) 
    GROUP BY MONTH(start_time), device_id, factor 

) usageids ON usageids.Month = months.Month 
      AND usageids.factor = factors.factor 
GROUP BY factors.factor, months.Month 
ORDER BY factors.factor, months.Month 

這是瘋狂的複雜的,但我試圖解釋意見每一部分做什麼。看到這個sqlfiddle:http://sqlfiddle.com/#!2/5c871/1/0

+0

非常感謝丹。我正在測試查詢。 – user2818666

+0

@丹我想每個月對不同設備的使用時間進行計數,但是這個查詢會給我一些設備的數量,請您幫忙? –

+0

@sash不是沒有更清楚地瞭解你在找什麼。有太多的方法來解釋你的要求。 http://sqlfiddle.com/#!2/5c871/13是一種可能性。 – Dan