2012-08-04 95 views
1

我認爲從我擁有的表格開始,我想要的結果是最簡單的。count rows where date is equal but but name by

Name | Date 
A | 03/01/2012 
A | 03/01/2012 
B | 02/01/2012 
A | 02/01/2012 
B | 02/01/2012 
A | 02/01/2012 
B | 01/01/2012 
B | 01/01/2012 
A | 01/01/2012 

我想我的查詢結果是:

Name | 01/01/2012 | 02/01/2012 | 03/01/2012 
A |  1  |  2  |  2 
B |  2  |  2  |  0 

所以基本上我想算具有相同日期的行數,但對於每一個人的名字。所以一個由日期組成的簡單羣組將不會執行,因爲它會將這些名稱合併在一起。然後我想輸出一個表格,顯示使用php的每個日期的計數。

我已經看到了答案建議是這樣的:

SELECT 
    NAME, 
    SUM(CASE WHEN GRADE = 1 THEN 1 ELSE 0 END) AS GRADE1, 
    SUM(CASE WHEN GRADE = 2 THEN 1 ELSE 0 END) AS GRADE2, 
    SUM(CASE WHEN GRADE = 3 THEN 1 ELSE 0 END) AS GRADE3 
FROM Rodzaj 
GROUP BY NAME 

所以我想會有一個辦法,我調整這一點,但我不知道是否有另一種方式,或者是最有效的? 我也許在想,如果while循環每次只輸出一個特定的名字和日期,那麼第一個結果就是A,01/01/2012,1,1下一個A,02/01/2012 ,2 - A,03/01/2012,3 - B,01/01/2012,2等等,那麼也許這將是可行的通過一種不同的技術,但不知道如果這樣的事情是可能的,如果它是有效的。

所以我基本上看看是否有人有任何想法,這是有點超出這個盒子,他們將如何比較。

我希望我解釋得很好,並提前感謝您的幫助。

+0

SAME PROBLEM ---------------- >> http://stackoverflow.com/questions/14805851/mysql -sum-column-values-based-on-the-the-the-table – Smoke 2014-06-16 09:18:50

回答

2

您必須在您的GROUP BY兩列:

SELECT name, COUNT(*) AS count 
FROM  your_table 
GROUP BY name, date 

這將讓每一個名字的計數 - >行格式的日期組合。既然你也想包括0計數如果名字沒有在特定日期的任何行,你可以使用:

SELECT  a.name, 
      b.date, 
      COUNT(c.name) AS date_count 
FROM  (SELECT DISTINCT name FROM your_table) a 
CROSS JOIN (SELECT DISTINCT date FROM your_table) b 
LEFT JOIN your_table c ON a.name = c.name AND 
          b.date = c.date 
GROUP BY a.name, 
      b.date 

SQLFiddle Demo

+0

那麼這比我想象的要簡單得多。按名稱分組首先將所有日期合併在一起,所以我不會想到按列添加額外的分組將會產生任何影響。非常驚訝,但很好,謝謝。 – mrmryb 2012-08-04 19:35:26

+0

偉大的補充,我想知道現在是否會更有效地使用第一個查詢選擇日期以及做一個php檢查匹配列或使用第二個查詢。儘管由於sql很快,我想第二個查詢仍然會更好。 – mrmryb 2012-08-04 19:45:11

2

你問一個「pivot 」。基本上,它就是這樣。一個關鍵點的真正問題是名稱名稱必須適應數據,這對於單獨的SQL是不可能的。

這裏是你如何做到這一點:

SELECT 
    Name, 
    SUM(`Date` = '01/01/2012') AS `01/01/2012`, 
    SUM(`Date` = '02/01/2012') AS `02/01/2012`, 
    SUM(`Date` = '03/01/2012') AS `03/01/2012` 
FROM mytable 
GROUP BY Name 

注意涼爽的方式,你可以SUM() MySQL中的狀態,becasue在MySQL true1false0,使總結的條件相當於數着數這是真的。

首先使用內部組沒有更高的效率。

+0

查看哪個查詢性能更好會很有趣,但是現在我向Zane提供了正確的答案,因爲我要求的是不同的東西,他肯定會提供,但也非常感謝您提供非常有用的答案。 – mrmryb 2012-08-04 19:43:26

0

萬一有人有興趣在什麼是最好的方法:

贊恩的第二個建議是最慢的,我裝在我做了其他兩個數據的三分之一,它花了相當長一段時間。也許在較小的表上它會更有效率,儘管我沒有使用大型表,但大約28,000行足以產生顯着的延遲,而between子句將結果減少到大約4000行。

波希米亞的答案給了我最少的代碼量,我投入了一個循環來創建所有的case語句,並且它相對容易。這種方法的好處是簡單,除了爲案例創建循環外,結果不需要任何PHP技巧,只需簡單的foreach即可獲得所有列。推薦給那些對php沒有信心的人。

但是,我發現Zane的第一個建議是最快的執行,儘管需要額外的PHP編碼,似乎我會堅持使用這種方法。這種方法的缺點是它只給出實際上有數據的日期,因此創建一個包含所有日期的表格會變得更加複雜一些。我所做的是創建一個變量,用於跟蹤它應該與每個錶行重置的表列的日期進行比較,當查詢結果等於該日期時,它會回顯該值,否則它會執行一次操作while循環回顯表格單元格爲0,直到日期匹配。它還必須進行檢查以查看'Name'值是否仍然相同,如果不是,則在填充任何缺失的單元格並將該行的末尾填入0之後切換到下一行。如果任何人有興趣看到代碼,你可以給我發消息。

兩種方法超過3個月的數據(每一天,所以約90 case語句列)的結果〜12,000行了28000:
波西米亞的拐點 - 〜0.158s(最高見過〜0.36s)
贊恩的雙分組由〜〜0.086s(最高可見〜0.15s)

相關問題