2012-12-27 39 views
1

我有以下用别名in_Degree语法不正确的查询和out_degree:MySQL的使用别名

insert into userData 
select user_name, 
     (select COUNT(*) from tweets where rt_user_name = u.USER_NAME)in_degree, 
     (select COUNT(*) from tweets where source_user_name = u.user_name)out_degree, 
     in_degree + out_degree(freq) 
    from users u 

查询的问题是在别名为频率选择列表中的第4个项目。我希望第4项具有in_degree + out_degree的值。蛮力非常缓慢的解决方案将是复制并通过两个子查询并添加它们。

  1. 如何使这个快速和简单的in_degree + out_degree?

回答

2

你可以使用子查询:

insert into userData 
select user_name, 
    in_degree, 
    out_degree, 
    in_degree + out_degree 
from 
(
    select user_name, 
    (select COUNT(*) from tweets where rt_user_name = u.USER_NAME)in_degree, 
    (select COUNT(*) from tweets where source_user_name = u.user_name)out_degree 
    from users u 
) src 

,或者您可能能够使用:

insert into userData 
select user_name, 
    count(distinct in_t.*) in_degree, 
    count(distinct out_t.*) out_degree, 
    count(distinct in_t.*) + count(distinct out_t.*) 
from users u 
left join tweets in_t 
    on u.USER_NAME = in_t.rt_user_name 
left join tweets out_t 
    on u.USER_NAME = out_t.source_user_name 
group by u.user_name 
+0

第二个查询需要一个'GROUP BY u.USER_NAME'工作和计数内'DISTINCT'以避免笛卡尔乘积创建多个计数。 –

+0

@ypercube你是对的,修正了 – Taryn

+0

我真的很喜欢子查询方法 – CodeKingPlusPlus

0

这应该工作:

insert into userData 
    SELECT T.user_name, 
     T.in_degree, 
     T.out_degree, 
     (T.in_degree + T.out_degree) as freq 
    FROM (SELECT user_name, 
      (select COUNT(*) from tweets where rt_user_name = u.USER_NAME) as in_degree, 
      (select COUNT(*) from tweets where source_user_name = u.user_name) as out_degree  
      FROM users u) T 
0

在一个快速的方式,我会做这样的事情:

insert into userData 
select 
    TMP.user_name, 
    TMP.in_degree, 
    TMP.out_degree, 
    (TMP.in_degree + TMP.out_degree) degreeSum 
from(
    select user_name, 
     (select COUNT(*) from tweets where rt_user_name = u.USER_NAME)in_degree, 
     (select COUNT(*) from tweets where source_user_name = u.user_name)out_degree 
    from users u 
) TMP 
2

正如您发现的那样,除了HAVING子句或ORDER BY子句之外,不能引用该选择列表中给出的别名。

一种选择是使用你的查询作为“内联视图”,并围绕它编写包装查询。

  • 移除第四个从查询中的选择列表(无效)的表达,
  • 用别名包裹查询在一组括号
  • 按照收盘括号(例如)■
  • 写一个查询,引用内联视图就好像它是一个表
  • 外部查询的选择列表可以引用内联视图中定义的“别名”。

但是,如果你想让这个“快速”,你可以考虑(作为一个选项)采取完全不同的方法。可以使用相关子查询来获得每个个体用户的计数,而不是使用相关子查询来计算所有用户的计数,然后使用LEFT JOIN运算符。

SELECT u.user_name 
    , IFNULL(i.cnt,0) AS in_degree 
    , IFNULL(o.cnt,0) AS out_degree 
    , IFNULL(i.cnt,0)+IFNULL(o.cnt,0) AS freq 
    FROM users u 
    LEFT 
    JOIN (SELECT rt_user_name, COUNT(*) AS cnt FROM tweets 
     GROUP BY rt_user_name) i 
    ON i.rt_user_name = u.user_name 
    LEFT 
    JOIN (SELECT source_user_name, COUNT(*) AS cnt FROM tweets 
     GROUP BY source_user_name) o 
    ON o.source_user_name = u.user_name 
+0

+1恕我直言,这应该也是这种情况下最快的一个 –

+0

@Sir Rufo:索引为'ON推文(rt_user_name)','ON推文(source_user_name)'和'ON用户(user_name)',这可能的确是最有效的方法。这些相关的子查询可以从“用户”表中为您的午餐(性能明智)用于大量的行。如果查询只查看用户表中的少量行,则相关子查询可能会更快。 – spencer7593

+1

我应该粗体显示“在这种情况下” - >所有用户。谈论索引还应包括使用用户ID(INT/BIGINT)而不是用户名(字符)来加速性能并降低内存消耗:o) –