Mysql 将列移动到专用表中

Mysql 将列移动到专用表中,mysql,sql,Mysql,Sql,除了之外,我喜欢将下载列移动到一个单独的表“下载”,该表包含特定下载的信息和时间戳 这里是 因此,我喜欢 ID referer domain code downloads ========================================================================= 1 example.com/siteA example.com codeone 2 2

除了之外,我喜欢将下载列移动到一个单独的表“
下载”
,该表包含特定下载的信息和时间戳

这里是

因此,我喜欢

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
这是我的,没有下载栏

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; 
编辑

此外,我喜欢和你在一起

如何获取推荐人的下载计数:

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

您的
分组依据
很好,只需加入
下载
计数(下载。*)

要更详细地了解
分组依据
:通常在SQL中,您需要
分组依据
每个未聚合的变量,即在我们的示例中
COUNT()
'ed。以下内容最适合您的需要:

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有一个
    groupby
    的“惰性”实现,这意味着如果在
    groupby
    中没有包含未聚合的变量,但它在组中是唯一的,那么这是有效的。这就是为什么您和我的第一个代码在MySQL中有效,但在其他系统上无效的原因。请参阅,尤其是关于“懒惰”实施的评论和链接
  • 另一方面,MySQL支持带有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
之前,首先应确保所有这些变量均
不为NULL
,以避免歧义

编辑

您还可以请求
引用进行分组,但也包括每个域的总和。在一个支持窗口函数(
COUNT(downloads.ID)OVER(partitionbydomain
)的系统中,这可能非常容易,但在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; 
另请参见下面的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 Fiddle:

按域分组

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

很长一段时间以来最好的问题,不难,但有所有的“要求”。好的,这在示例中有效,谢谢。不幸的是,在我的应用程序中没有。
计数(downloads.ID)
总是返回表中的行数。最好是像
COUNT WHERE user\u id=download这样的方法。user\u id
你能改变你的示例来反映这个差异吗?--你确定加入下载表成功吗?再次检查它是否只根据需要的用户id加入。好的,我的错:如果我获取某个域的总数。我如何获取引用者的数量?@revaxarts我还编辑了我关于分组依据和汇总的回复。您能否完成以获取提到的结果?
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