连接两个表中存在的数据并聚合非连接数据

时间:2013-09-11 07:06:41

标签: asp.net sql-server linq linq-to-sql join

我有两张桌子

Name    | ID      | 
--------+---------+
A       | 3       | 
A       | 5       | 
B       | 1       | 



 ID     | Count   | 
--------+---------+
1       | 10      | 
2       | 50      | 
3       | 15      | 
6       | 20      | 

我想生成一些连接这两个表的ID以及聚合不匹配条目的结果的东西

Name    | ID      | Count
--------+---------+----------
A       | 3       | 15
A       | 5       | 0 *//(doesn't exists)*
A       | others  | 80 *//(10 (ID 1) + 50 (ID 2) + 20 (ID 6))*
B       | 1       | 10
B       | others  | 85 *//(50 (ID 2) + 15 (ID 3) + 20 (ID 6))*

直到现在我可以获得匹配的项目,但无法获得不匹配的聚合。

我觉得在每个ID列表上执行except并聚合不匹配的ID并不是一个优雅的解决方案。

希望找到更优雅的解决方案。

修改 我忘了提到我正在使用SQL server。 oracle解决方案在我的场景中没有任何用处,但在Oracle用户的类似场景中也会有所帮助。

3 个答案:

答案 0 :(得分:1)

这个怎么样: 获取匹配的项目并使用第二个查询进行联合。 第二个查询将选择名称,“其他”,总和(计数),并将在名称上分组,其中id不在第一个表的ID中(您可以使用子查询检查)。

如果您愿意,我可以输入,您看起来就像知道自己在做什么,只需要了解如何做到这一点。

答案 1 :(得分:1)

在oracle的情况下使用nvl。 sql server ifnull()和mysql isnull(),左右外部联合而不是全外部

select name, id, sum(cnt) from
(
select name, nvl(to_char(a.id), 'others') id, nvl(b.count,0) cnt 
from table1 a 
     full outer join 
     table2 b on a.id = b.id)
group by name, id

答案 2 :(得分:0)

LINQ解决方案就是:

from n in Names
join c in Counts on n.ID equals c.ID into outer
select new { n.Name, 
             ID = outer.Count() > 1 ? "others" : n.ID.ToString(),
             Sum = ((int?)outer.Sum(x => x.Count)) ?? 0 }

它相当于外部联接,但也有一些技巧可以将null转换为0。在linq-to-sql中,这很好地转换为SQL。因为它被翻译成SQL outer.Count(),所以outernull时不会抛出异常。