Mat*_* M. 8 c# linq grouping aggregate-functions linq-to-sql
我想将以下查询转换为LINQ语法.我在设法让它发挥作用方面遇到了很多麻烦.我实际上尝试从LINQ开始,但发现如果我以相反的方式编写它,我可能会有更好的运气.
SELECT
pmt.guid,
pmt.sku,
pmt.name,
opt.color,
opt.size,
SUM(opt.qty) AS qtySold,
SUM(opt.qty * opt.itemprice) AS totalSales,
COUNT(omt.guid) AS betweenOrders
FROM
products_mainTable pmt
LEFT OUTER JOIN
orders_productsTable opt ON opt.products_mainTableGUID = pmt.guid
LEFT OUTER JOIN orders_mainTable omt ON omt.guid = opt.orders_mainTableGUID AND
(omt.flags & 1) = 1
GROUP BY
pmt.sku, opt.color, opt.size, pmt.guid, pmt.name
ORDER BY
pmt.sku
Run Code Online (Sandbox Code Playgroud)
最终结果是一个表格,向您显示有关产品的信息,如上所示.如何使用理解语法以LINQ格式编写此查询?
另外,我可能想要添加其他过滤器(例如,对orders_mainTable).
这是我尝试工作的一个例子,并且非常接近但不确定它是否是"正确"方式,并且无法按照orders_productsTable的大小和颜色对其进行分组.
from pmt in products_mainTable
let Purchases =
from opt in pmt.orders_productsTable
where ((opt.orders_mainTable.flags & 1) == 1)
where ((opt.orders_mainTable.date_completedon > Convert.ToDateTime("01/01/2009 00:00:00")))
select opt
orderby pmt.sku
select new {
pmt.guid,
pmt.sku,
pmt.name,
pmt.price,
AvgPerOrder = Purchases.Average(p => p.qty).GetValueOrDefault(0),
QtySold = Purchases.Sum(p => p.qty).GetValueOrDefault(),
SoldFor = Purchases.Sum(p => p.itemprice * p.qty).GetValueOrDefault()
}
Run Code Online (Sandbox Code Playgroud)
*编辑:
为了更明确一点,你可以理解我想要做的事情,这里有一些更多的解释.
产品存储在products_mainTable中订单存储在orders_mainTable中已订购的产品存储在orders_productsTable中
我想基于产品,订单等创建多个报告,钻取数据并找到有意义的位以显示给最终用户.
在这种情况下,我试图显示在一段时间内购买了哪些产品,并且是最受欢迎的产品.卖出了多少,价格是多少,每个订单的突破是多少.也许不是最好的顺序,但我只是在尝试并选择了这个.
所有表都与其他表有关系.所以从产品表中,我可以了解订购该产品的订单等.
我遇到的最大问题是理解LINQ如何工作,尤其是分组,聚合数据,扩展,子查询等.这很有趣,但它开始变得令人沮丧,因为我很难找到关于如何做到这一点的详细解释.
我也是LINQ的初学者.我不知道这是否是通过多个字段进行分组的正确方法,但我认为您必须将这些分组字段转换为代表键.因此,假设您的所有分组字段都是字符串或整数,您可以按如下方式创建密钥:
var qry = from pmt in products_mainTable
join opt in orders_productsTable on pmt.guid equals opt.products_mainTableGUID
join omt in orders_mainTable on opt.orders_mainTableGUID equals omt.guid
where (opt.orders_mainTable.flags & 1) == 1
group omt by pmt.sku + opt.price + opt.size + pmt.guid + pmt.name into g
orderby g.sku
select new
{
g.FirstOrDefault().guid,
g.FirstOrDefault().sku,
g.FirstOrDefault().name,
g.FirstOrDefault().color,
g.FirstOrDefault().price,
AvgPerOrder = g.Average(p => p.qty).GetValueOrDefault(0),
QtySold = g.Sum(p => p.qty).GetValueOrDefault(),
SoldFor = g.Sum(p => p.itemprice * p.qty).GetValueOrDefault()
};
Run Code Online (Sandbox Code Playgroud)
我没有测试过,所以请看看这对你有什么帮助.
布鲁诺,非常感谢你的帮助!FirstOrDefault() 可能是最大的帮助。根据您所做的一些工作以及另一个资源,我想出了以下似乎效果很好的内容!下面的 LINQ 查询几乎完全复制了我上面发布的 SQL。
这是我在 LINQ 中执行 LEFT OUTER JOIN 时发现的其他资源:博客文章
最终答案:
from pmt in products_mainTable
join opt in orders_productsTable on pmt.guid equals opt.products_mainTableGUID into tempProducts
from orderedProducts in tempProducts.DefaultIfEmpty()
join omt in orders_mainTable on orderedProducts.orders_mainTableGUID equals omt.guid into tempOrders
from ordersMain in tempOrders.DefaultIfEmpty()
group pmt by new { pmt.sku, orderedProducts.color, orderedProducts.size } into g
orderby g.FirstOrDefault().sku
select new {
g.FirstOrDefault().guid,
g.Key.sku,
g.Key.size,
QTY = g.FirstOrDefault().orders_productsTable.Sum(c => c.qty),
SUM = g.FirstOrDefault().orders_productsTable.Sum(c => c.itemprice * c.qty),
AVG = g.FirstOrDefault().orders_productsTable.Average(c => c.itemprice * c.qty),
Some = g.FirstOrDefault().orders_productsTable.Average(p => p.qty).GetValueOrDefault(0),
}
Run Code Online (Sandbox Code Playgroud)