2012-12-27 40 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) –