2014-08-28 51 views
0

對MySQL比較新,但我已經使用它幾個月了,並且被要求根據一些數字來做一些數學運算。想象一下,由於有很多記錄,所以讓mysql爲我做這件事情要好得多。我會盡我所能解釋我所追求的;這裏有一小部分結果。從兩個單獨的查詢中對列進行數學運算

SELECT attempt_number, date(initiated_at) as day,phone_number, count(*) FROM table WHERE phone_number IN (<a bunch of numbers>) AND initiated_at > '2014-08-01 00:00:00' and initiated_at < date_sub(now(), interval 5 minute) and attempt_number in (1, 2) and attempt_number IS NOT NULL group by phone_number,day, attempt_number; 


+----------------+------------+--------------+----------+ 
| attempt_number | day  | phone_number | count(*) | 
+----------------+------------+--------------+----------+ 
|    1 | 2014-08-04 | 0000000000 |  2 | 
|    2 | 2014-08-04 | 0000000000 |  1 | 
+----------------+------------+--------------+----------+ 

以上結果是單日和電話號碼(實際上有數千條記錄)的例子。可以假定所有phone_number記錄都有一個attempt_number 1,但並非全部都有2.我最終以每天爲基礎(如上面的「日期」一節所設置的),調用的百分比獲取第二次嘗試的電話號碼列表。對於上述結果,我需要這樣的輸出:

+------------+--------------+------------+ 
| day  | phone_number | percentage | 
+------------+--------------+------------+ 
| 2014-08-04 | 0000000000 |   67 | 
+------------+--------------+------------+ 

這是否有意義?我嘗試了一些有變數的巫術,但我被掛斷了。也許這不是解決這個問題的最好方法。 (我知道如何進行數學和變量的工作,只是因爲這些結果是如何按天分組的,而形成的)。

謝謝!

回答

1

你只需要有條件聚集:

SELECT date(initiated_at) as day, attempt_number, 
     sum(attempt_number = 1) as attempt1, 
     sum(attempt_number = 2) as attempt2, 
     avg(attempt_number = 1)*100 as percentage 
FROM table 
WHERE phone_number IN (<a bunch of numbers>) AND 
     initiated_at > '2014-08-01 00:00:00' and 
     initiated_at < date_sub(now(), interval 5 minute) and 
     attempt_number in (1, 2) and 
     attempt_number IS NOT NULL 
group by date(initiated_at), phone_number; 

的MySQL把布爾數字,真真切切是 「1」 和假是 「0」。然後,您可以使用sum()來計算事情成立的次數。 avg()返回某些事情成立的時間比例。

+0

+1。這就是我要做的,這是最直接的方法。請注意,SUM()聚合有可能返回NULL;我們可能想要將這些NULL值作爲零來處理,並使用適當的包裝函數來將零值替換爲零。請注意,'attempt_number IS NOT NULL'謂詞對於'attempt_number IN()'謂詞是多餘的。具有滿足IN()謂詞的'attempt_number'的任何行都保證爲「NOT NULL」。 – spencer7593 2014-08-28 02:59:41

+0

@ spencer7593。 。 。他們不能返回NULL。 where子句將行限制爲至少有一行包含這些值的值。條件評估爲'0'或'1',所以不可能有'NULL'值(如果'attempt_number'爲'NULL'則該行將被過濾掉。 – 2014-08-28 03:16:06

+0

* DOH!*是的。我錯了。你絕對是對的。我們已經保證'attempt_number'不是NULL(我在我的評論中實際上已經提到了這一點)。與non-NULL值的比較保證* not *返回NULL。 – spencer7593 2014-08-28 03:47:01

1
SELECT day, phone_number, FLOOR(100 * count1/(count1+count2)) AS percentage 
FROM (
    SELECT date(initiated_at) AS day, phone_number, 
      IFNULL(SUM(attempt_number = 1), 0) AS count1, 
      IFNULL(SUM(attempt_number = 2), 0) AS count2 
    FROM table 
    WHERE ... 
    GROUP by day, phone_number) AS subquery 
+0

這應該返回指定的結果。但我會選擇避免實現派生表的性能開銷;沒有必要,結果可以在沒有內聯視圖的情況下獲得。 – spencer7593 2014-08-28 03:06:09

+0

這需要重複'IFNULL(SUM(...))'表達式,這使查詢非常難以閱讀。如果表現有問題,他可以用這種方式重寫。 – Barmar 2014-08-28 03:16:56

0

簡單的一招

SELECT DATE(initiated_at) AS day,phone_number, 
COUNT(CASE attempt_number WHEN 2 THEN 1 ELSE NULL END)/COUNT(CASE attempt_number WHEN 1 THEN 2 ELSE NULL END) * 100 
FROM TABLE 
WHERE phone_number IN ('000') 
AND attempt_number IN (1, 2) AND attempt_number IS NOT NULL GROUP BY phone_number,DATE(initiated_at); 
相關問題