2014-06-16 68 views
3

非常簡單的問題。我想要做的是從一個表中選擇所有列,並從另一個表中選擇一列(可以有多個匹配的行)的總和。多表連接與聚合(mssql/sql服務器)

例子:

table ta (eid, uid, name, year, etc, etc, etc) 
table tb (eid, uid, name, year, amount, etc, etc) 

eid - 不會兩個表之間的匹配 uid, name, year - 將在兩個表

所以我想從表ta拔出所有列,簡單的搭配:

select * from ta where eid='value'; 

我想加入表tb的金額欄到m y結果集,簡單:

select a.*, b.amount 
from ta a 
inner join tb b on a.year=b.year 
where a.eid='value'; 

很好,這工作正常。但是如果我在表tb中有多行呢?

執行:

select a.*, sum(b.amount) 
from ta a inner join tb b on a.uid=b.uid 
where a.year='value'; 

給了我以下錯誤:

Column 'ta.eid' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

所以我補充一下:

select a.*, sum(b.amount) 
from ta a inner join tb b on a.uid=b.uid 
where a.year='value' group by ta.uid; 

我也得到了同樣的錯誤!

但是,如果我我的查詢更改爲:

select a.uid, a.year, sum(b.amount) 
from ta a inner join tb b on a.uid=b.uid 
where a.year='value' 
group by ta.uid, ta.year; 

它的工作原理,但現在我有三列,而不是我想要的所有列。

因此,在這一點上我的問題是:是否有更好,更簡潔的方式來構建此查詢,而不是手動輸入我想從兩個帶有GROUP BY子句的表中拉出的所有列?

+0

對於它的價值[它不是在生產代碼中使用'SELECT *'好習慣](http://sqlblog.com/blogs/aaron_bertrand/存檔/ 2009/10/10 /壞習慣,對開球使用選-省略最柱list.aspx)。編寫查詢時可能會節省30秒,但從長遠來看可能會讓您花費更多。 – GarethD

+0

我之所以在一個表中使用'Select *',是因爲有97%的列被填充到更新表單中,隨後將更新數據庫中的表記錄。 – iiminov

+0

其實我的問題甚至有道理?我應該多說一點還是提供一個更好的表列結構或其他東西? – iiminov

回答

7

你可以在一個子查詢preaggregate:

select a.*, b.sumb 
from ta a left join 
    (select b.uid, sum(b.amount) as sumb 
     from tb b 
     group by b.uid 
    ) b 
    on a.uid=b.uid 
where a.year = 'value'; 
+0

看起來很有意思,但是會引發錯誤,因爲它不包含在聚合函數或GROUP BY子句中,所以'Column'b.uid'在選擇列表中是無效的。' 這與它有什麼關係因爲金額存儲了一個'varchar'格式的字符串,所以我做'總和(將(b.amount作爲貨幣))彙總爲sumb'? – iiminov

+0

@GarethD。 。 。謝謝。謎團已揭開。 –

+0

的確,「b.uid組合」解決了令我煩惱的錯誤。歡呼的小夥子們。 – iiminov