问题 `SELECT MIN(ZoneMin),MAX(ZoneMin)FROM Plant`作为LINQ to SQL


从LINQ尝试时,这个相当简单的SQL查询被证明是非常令人困惑的。

我有一个SQL表 Plant 与列 ZoneMin

我想找到列中值的最小值和最大值。
T-SQL的答案很简单:

SELECT MIN(ZoneMin), MAX(ZoneMin) FROM Plant

什么是LINQ查询,可以让我这个(或类似的)SQL?

我已经对.Aggregate()和.GroupBy()进行了各种尝试而没有运气。我也看了几个看似相似的问题。

这可以通过应用于结果数组的方法简单地实现,但是当在T-SQL中如此简单时,我不需要从每个SQL行传输值。


11005
2018-01-12 18:02


起源



答案:


要获得与原始查询相同的性能,您需要使用分组(通过常量来最小化影响,例如 0),以便您可以在同一查询中两次引用同一组记录。使用表名会导致在每个引用上生成新查询。请尝试以下方法:

(from plant in db.Plants
 group plant by 0 into plants
 select new { Min = plants.Min(p => p.ZoneMin), Max = plants.Max(p => p.ZoneMin) }
).Single()

这会产生以下查询:

SELECT MIN(plants.ZoneMin), MAX(plants.ZoneMin)
FROM (SELECT 0 AS Grp, ZoneMin FROM Plants) AS plants
GROUP BY plants.Grp

在优化器完成之后,它会向您的查询发出类似的内容,至少根据SQL Server Management Studio。


14
2018-01-12 20:24



做得很好!谢谢Allon。我倾向于忘记尝试“一组不变”的伎俩。 - Peter
@Peter:那你领先于我 - 在研究你的问题之前我甚至没有听说过这个伎俩。 - Allon Guralnek


答案:


要获得与原始查询相同的性能,您需要使用分组(通过常量来最小化影响,例如 0),以便您可以在同一查询中两次引用同一组记录。使用表名会导致在每个引用上生成新查询。请尝试以下方法:

(from plant in db.Plants
 group plant by 0 into plants
 select new { Min = plants.Min(p => p.ZoneMin), Max = plants.Max(p => p.ZoneMin) }
).Single()

这会产生以下查询:

SELECT MIN(plants.ZoneMin), MAX(plants.ZoneMin)
FROM (SELECT 0 AS Grp, ZoneMin FROM Plants) AS plants
GROUP BY plants.Grp

在优化器完成之后,它会向您的查询发出类似的内容,至少根据SQL Server Management Studio。


14
2018-01-12 20:24



做得很好!谢谢Allon。我倾向于忘记尝试“一组不变”的伎俩。 - Peter
@Peter:那你领先于我 - 在研究你的问题之前我甚至没有听说过这个伎俩。 - Allon Guralnek