来自子句的别名

时间:2011-09-19 09:42:31

标签: c# linq

假设我有2个表

出售

> department  sale  
  a             20 
  a             30  
  b             25

返回

> department   return 
     a           21            
     a           23 
     a           24 
     c           29

现在我希望结果为

Department   sale  return    
  a           50     68
  b           25      0
  c            0      29

到目前为止我的尝试。

var saleData = from b in Sale.AsEnumerable()
               join a in return.AsEnumerable()
               on  b["Department"] equals a["Department"] 

               group b by b.Field<string>("Department") into g

               let list = g.ToList()
               select new
               {
                   departmentId = g.Key,
                   departmentCount = list.Count,
                   saleSum = list.Sum(x => x.Field<double>("sale")),
                   returnSum = list.Sum(x => x.Field<double>("Return"))
               };

但上述查询无效,因为Return列不属于列表。

如何按部门从a和b以及组中选择数据?

1 个答案:

答案 0 :(得分:1)

使用此初始化

DataTable Sale=new DataTable("sale");
Sale.Columns.Add("department",typeof(string));
Sale.Columns.Add("sale",typeof(double));
Sale.Rows.Add("a",20);
Sale.Rows.Add("a",30);
Sale.Rows.Add("b",25);

DataTable Return=new DataTable("Return");
Return.Columns.Add("department",typeof(string));
Return.Columns.Add("return",typeof(double));
Return.Rows.Add("a",21);
Return.Rows.Add("a",23);
Return.Rows.Add("a",24);
Return.Rows.Add("c",29);

您需要以下

var salesData = from b in Sale.AsEnumerable()
                join a in Return.AsEnumerable()
                on b["department"] equals a["department"]
                group new {b,a} by b.Field<string>("department") into g
                select new {
                    departmentId=g.Key,
                    departmentCount=g.Count(),
                    saleSum=g.Sum(x=>x.b.Field<double>("sale")),
                    returnSum=g.Sum(x=>x.a.Field<double>("return"))
                };

但是,此代码不会执行您需要的求和和完全外连接

您实际需要的是以下

// Calculate the sale totals
var SaleSums = from b in Sale.AsEnumerable()
           group b by b.Field<string>("department") into g
           select new {
                department=g.Key,
                sale=g.Sum(x=>x.Field<double>("sale"))
        };

// Calculate the return totals
var ReturnSums = from a in Return.AsEnumerable() 
           group a by a.Field<string>("department") into g
           select new {
               department=g.Key,
               Return=g.Sum(x=>x.Field<double>("return"))
        };

// do a left outer join to find all the sale totals with the matching (if present) return totals
var leftData= from b in SaleSums
                join a in ReturnSums
                on b.department equals a.department into left
                from l in left.DefaultIfEmpty()
                select new {a=l,b};

// do a left outer join to find all the return totals without the matching sale totals
// (hence the r==null check)
var rightData=  from a in ReturnSums
                join b in SaleSums
                on a.department equals b.department into right
                from r in right.DefaultIfEmpty()
                where r == null
                select new {a,b=r};


var salesData = from d in leftData.Union(rightData)         
                select new {
                    department=d.a==null ? d.b.department : d.a.department,
                    sale=d.b==null ? 0 : d.b.sale,
                    Return = d.a==null ? 0 : d.a.Return
                };