1

我有以下语法不正确的查询,别名为 in_Degree 和 out_degree:

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 项别名为 freq。我希望第 4 项的值为 in_degree + out_degree。蛮力极慢的解决方案是复制并通过两个子查询并添加它们。

  1. 我怎样才能让它变得像 in_degree + out_degree 一样快速和简单?
4

4 回答 4

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
于 2012-12-27T22:25:04.897 回答
2

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

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

  • 从查询的选择列表中删除第 4 个(无效)表达式,
  • 将您的查询包装在一组括号中
  • 在结束括号后面加上别名 (eg) s
  • 围绕它写一个查询,引用内联视图,就好像它是一个表一样
  • 外部查询上的选择列表可以引用内联视图中定义的“别名”。

但是,如果您想让这个“快速”,您可能会考虑(作为一种选择)采取完全不同的策略。您可以获取所有用户的计数,而不是使用相关子查询来获取每个用户的计数,然后使用 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
于 2012-12-27T22:39:52.217 回答
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
于 2012-12-27T22:25:16.433 回答
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
于 2012-12-27T22:26:04.110 回答