将列移动到专用表中

时间:2014-03-06 10:22:10

标签: mysql sql

除了 this questions 之外,我还希望将下载列移到单独的表格中,而{34} 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

2 个答案:

答案 0 :(得分: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 未聚合的每个变量,即在我们的案例中{{1} }“主编。以下是最好的,接近​​您的需求:

COUNT()

让我更详细地介绍一下MySQL的两个细节:

  • MySQL具有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; 的“懒惰”实现,这意味着如果您未在GROUP BY中包含非聚合变量,但它在组内是唯一的,那么这是有效的。这就是为什么你和我的第一个代码在MySQL中有效但不在其他系统上的原因。请参阅GROUP BY query that works in MySQL is rejected by PostgreSQL,特别是关于'lazy'impementation的评论和链接。
  • 从好处来看,MySQL支持GROUP BY,如果您在不同的字段上聚合,它可能对您有用,也可能没用。如果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之前,首先应确保所有这些变量都是NOT NULL,以避免歧义。

修改

您还请求ROLLUP个参与者,但也包含每个域的总和。这在支持窗口函数(GROUP BY)的系统中可能非常简单,但在MySQL中最好的方法是从两个查询中构建它。

您可以先定义包含所有信息的视图:

COUNT(downloads.ID) OVER (PARTITION BY domain

然后只需通过referer和来自此视图的域数据收集:

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;

另见http://sqlfiddle.com/#!2/131a0/2/0

答案 1 :(得分: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