2014-03-06 54 views
4

除了this questions我喜歡下載列移動到一個單獨的表「downloads」,其中包含了一定下載的信息和時間戳移動列到奉獻表

這裏的the Fiddle

正如我喜歡有

ID referer    domain    code  downloads 
========================================================================= 
1 example.com/siteA example.com   codeone 2 
2 example2.com/siteA example2.com  (null)  2 
3 example.com/siteB example.com   codetwo 0 
4 example2.com/siteB example2.com  (null)  2 

結果這是我current attempt沒有下載列

SELECT users.*, 
     codes.code 
     FROM users 
     LEFT JOIN (codes 
        INNER JOIN codes_users 
          ON codes.id = codes_users.code_id) 
       ON users.id = codes_users.user_id 
GROUP BY users.id; 

編輯

而且我喜歡group by the domain

GROUP BY users.domain; 

我如何獲得下載數引用站點的:

ID referer    domain  code  dl_for_domain dl_for_referer 
================================================================================== 
1 example.com/siteA example.com codeone 2    2 
2 example2.com/siteA example2.com (null) 4    2 
+0

最好的問題在很長一段時間,不硬但所有的 「要求」。 – Mihai

回答

4

您的GROUP BY適合您,請加入downloadsCOUNT(downloads.*)

http://sqlfiddle.com/#!2/6ca2b/4/0

SELECT users.*, 
     codes.code, 
     COUNT(downloads.ID) 
     FROM users 
     LEFT JOIN (codes 
        INNER JOIN codes_users 
          ON codes.id = codes_users.code_id) 
       ON users.id = codes_users.user_id 
     LEFT JOIN downloads ON 
      users.id = downloads.user_id 
GROUP BY users.id; 

要獲得的更多細節GROUP BY:一般的SQL,則需要GROUP BY每個變量未聚合,即在我們的例子COUNT()「版。

SELECT users.referer, 
     users.domain, 
     codes.code, 
     COUNT(downloads.ID) 
     FROM users 
     LEFT JOIN (codes 
        INNER JOIN codes_users 
          ON codes.id = codes_users.code_id) 
       ON users.id = codes_users.user_id 
     LEFT JOIN downloads ON 
      users.id = downloads.user_id 
GROUP BY users.referer, 
     users.domain, 
     codes.code; 

,讓我走成兩個詳情關於MySQL特別:

  • MySQL有一個「懶惰」的實施GROUP BY,這意味着你需要以下將是最好的,靠近如果您在GROUP BY中不包含未分類的變量,但它在分組內是唯一的,那是有效的。這就是爲什麼你和我的第一個代碼在MySQL中有效,但不在其他系統上。請參閱GROUP BY query that works in MySQL is rejected by PostgreSQL,特別是關於「懶惰」障礙的評論和鏈接。
  • 另一方面,MySQL支持WITH ROLLUP,如果你在不同的領域進行聚合,這對你可能有用,也可能沒有用。在ROLLUP的情況下,變量的順序很重要,所以請試驗一下。請參閱:

    SELECT codes.code, 
         users.domain, 
         users.referer, 
         COUNT(downloads.ID) 
         FROM users 
         LEFT JOIN (codes 
            INNER JOIN codes_users 
              ON codes.id = codes_users.code_id) 
           ON users.id = codes_users.user_id 
         LEFT JOIN downloads ON 
          users.id = downloads.user_id 
    GROUP BY codes.code, 
          users.domain, 
          users.referer   
    WITH ROLLUP; 
    

在這種情況下NULL變量意味着所有行獨立變量的集合。 (這讓我想起,在使用ROLLUP以避免模糊不清之前,首先應確保所有這些變量均爲NOT NULL

編輯

還要求GROUP BY參照網址,也包括爲每個域的款項。在支持窗口函數的系統(COUNT(downloads.ID) OVER (PARTITION BY domain)中這可能非常容易,但在MySQL中最好的方法是從兩個查詢中構建它。

您可以先定義一個包含所有信息的視圖:

create view v as 
select users.domain, 
     downloads.ID, 
     referer, 
     code, 
     downloads.user_id 
FROM users 
     LEFT JOIN (codes 
        INNER JOIN codes_users 
          ON codes.id = codes_users.code_id) 
       ON users.id = codes_users.user_id 
     LEFT JOIN downloads ON 
      users.id = downloads.user_id; 

然後,只需通過引用者,並從該視圖域數據同時收集:

select * from 
(
    SELECT 
     referer, 
     domain, 
     code, 
     COUNT(user_id) AS dl_for_referer 
    FROM v 
    GROUP BY referer 
) group_referrer JOIN 
(
    SELECT 
     domain, 
     COUNT(ID) AS dl_for_domain 
    FROM 
     v 
    GROUP BY domain 
) group_domain ON 
    group_referrer.domain=group_domain.domain; 

也看到http://sqlfiddle.com/#!2/131a0/2/0

+0

好的這個例子,謝謝。不幸的是它不在我的應用程序中。 COUNT(downloads.ID)總是返回表中的行數。最好是像'COUNT WHERE user_id = download.user_id' – Xaver

+0

你能改變你的例子來反映這種差異嗎? - 您確定下載表的JOIN成功嗎?仔細檢查它是否僅根據所需的user_id進行連接。 –

+0

好的,我的錯:如果我[按域分組](http://sqlfiddle.com/#!2/6ca2b/9),我得到了某個域的總數。如何獲取引薦者的金額? – Xaver

1

下面試試SQL:

SELECT u.id, u.referer, u.domain, c.code, count(d.id) FROM users u 
LEFT JOIN codes_users cu ON cu.user_id = u.id 
LEFT JOIN codes c ON c.id = cu.code_id 
LEFT JOIN downloads d ON d.user_id = u.id 
GROUP BY u.id; 

SQL小提琴:http://sqlfiddle.com/#!2/6ca2b/25/0

GROUP BY DOMAIN

SELECT u.id, u.referer, u.domain, c.code, count(d.id) downloads FROM users u 
LEFT JOIN codes_users cu ON cu.user_id = u.id 
LEFT JOIN codes c ON c.id = cu.code_id 
LEFT JOIN downloads d ON d.user_id = u.id 
GROUP BY u.domain with rollup 
having u.domain is not null 

輸出

ID REFERER     DOMAIN   CODE   DOWNLOADS 
1 example.com/siteA  example.com  codeone  2 
2 example2.com/siteA  example2.com  (null)  4