代码之家  ›  专栏  ›  技术社区  ›  Ralph Shillington

如何在一组行上生成多个聚合

  •  1
  • Ralph Shillington  · 技术社区  · 14 年前

    我很难映射这样一个简单的T-SQL查询

    select min(price) as MinPrice, max(price) as MaxPrice, avg(price) as AvgPrice
    from titles
    

    对于这样的LINQ表达式:

    var answer = from t in Titles
    select new { MinPrice=Min(t.Price), MaxPrice=Max(t.Price), AvgPrice=Avg(t.Price)};
    

    显然,这不起作用,因为在这种情况下,Min不存在。我也知道需要某种类型的group子句,但是由于在原始的T-SQL语句中没有group by,所以我不确定这个linq查询中的group by如何应用。

    我使用的是EF4,但在本例中,我怀疑这是否重要。

    2 回复  |  直到 14 年前
        1
  •  2
  •   Thomas Levesque    14 年前

    不确定它是否适用于EF,但您可以尝试类似的方法:

    var query =
        from p in products
        group p by 0 into g
        select new
        {
            Min = g.Min(p => p.Price),
            Max = g.Max(p => p.Price),
            Avg = g.Average(p => p.Price)
        };
    var result = query.First();
    

    编辑:刚刚用linqpad和linq to-sql尝试过,它可以工作…所以它也可能在英孚工作


    上面的查询生成以下SQL:

    SELECT TOP (1) [t2].[value] AS [Min], [t2].[value2] AS [Max], [t2].[value3] AS [Avg]
    FROM (
        SELECT MIN([t1].[Price]) AS [value], MAX([t1].[Price]) AS [value2], AVG([t1].[Price]) AS [value3]
        FROM (
            SELECT @p0 AS [value], [t0].[Price]
            FROM [Product] AS [t0]
            ) AS [t1]
        GROUP BY [t1].[value]
        ) AS [t2]
    

    (the SELECT TOP(1) 只有部分是因为 First )

    这显然不是最佳的,但我认为SQL Server足够聪明,可以将其优化为更简单的…

        2
  •  0
  •   Grozz    14 年前
    var prices = titles.Select(t => t.Price);
    var answer = new { min = prices.Min(), max = prices.Max(), avg = prices.Average(); }