2011-08-24 121 views
1

我有一个返回Linq查询:MAX在WHERE

Item { 
    DateTime entryDate 
    ..... 
} 

我喜欢的结果与另一个表结合这个查询的一个长的查询

Value { 
    DateTime date, 
    double value 
} 

使得如果entryDate> = CUTOFF,然后取CUTOFF上的值,否则取entryDate上的值。换句话说,我想实现:

SELECT Item.*, Value.value WHERE 
MIN(Item.entryDate, CUTOFF) == Value.date 

对不起,我的语法,但这就是主意。

编辑:一些试验和错误后,我想出了这个LINQ到SQL查询:

from iValue in Values 
join iItem in ... (long query) 
let targetDate = iItem.EntryDate > CUTOFF ? iItem.EntryDate : CUTOFF 
where iValue.Date == targetDate 
select new 
{ 
    iItem, 
    targetDate, 
    iValue  
} 

感谢您的帮助。

+1

您使用的是什么LINQ提供程序? LINQ to SQL? LINQ to Entities?还有别的吗? – svick

+0

我正在使用linq到sql –

回答

0
yourLongQuery.Where(y => y.Item.entryDate == Value.date || CUTOFF == Value.date) 
      .Select(x => new { 
           entrydate = (x.Item.entryDate < CUTOFF ? x.Item.entryDate : CUTOFF), 
           /*rest of x.Item properties here */ , 
           x.Value.date, 
           x.Value.value 
           }); 

过滤查询,合并两个项目成一个项目和修改的第一项

+0

为什么有'Where'语句? –

+0

长查询项返回Item。它如何加入价值? 'y.Item.entryDate == Value.date' - 值不在范围内? –

+0

@Candy对不起误解你的原始问题 – msarchet

0

使得如果entryDate> = CUTOFF,再乘上CUTOFF值,否则 取的值上entryDate。换句话说,我想实现: SELECT *项目,Value.value WHERE MAX(Item.entryDate,截留)== Value.date

这是矛盾的 - 你想if entryDate >= CUTOFF then take the value on CUTOFF imples。 MIN(Item.entryDate, CUTOFF),而不是MAX

话虽如此,你只是想选择value.Value匹配您的查询的每个项目。每个项目都应该查找与您的MAX(或者我相信,MIN)声明相匹配的相关值。

query.Select(item => 
{ 
    var matchingValue = Values.Single(v => 
     v.date == Min(item.entryDate, CUTOFF)); 
    return new { item, matchingValue.value }; 
}); 

这将返回一个IQueryable的匿名{ Item, double }对象。


如果您需要将此作为单个SQL语句执行,您需要进行一些重构。一个好的开始是将matchingValue换成一个声明。

query.Select(item => new { item, context.Values.Single(v => 
    v.date == Min(item.entryDate, CUTOFF)).value }); 

我没有一个Visual Studio在我的面前,以确认,但我不知道该Math.Min功能在LINQ到SQL映射。我们假设它不是。

query.Select(item => new { item, context.Values.Single(v => 
    v.date == (item.entryDate < CUTOFF ? item.entryDate : CUTOFF)).value }); 

我认为,将解析为一个单一的查询,如果您有.ToList()执行它,但无法证实,直到我有一些工具在我的面前。用SQL分析器测试它确定。

+0

这是否会被翻译成一个巨大的SQL? –

+0

如果你愿意,你可以把它改成一个'巨大的SQL',但这是一个需求吗? –

0

假设你从Item查询返回的数据,且该Value表相对较小,那么这是一个很好的路要走:

var lookup = values.ToLookup(v => v.date, v => v.value); 

var query = 
    from i in items 
    let c = i.entryDate < CUTOFF ? i.entryDate : CUTOFF 
    let v = lookup[c].FirstOrDefault() 
    select new 
    { 
     Item = i, 
     Value = v, 
    }; 

ToLookup扩展是非常有用的,常常被忽视。

+0

ToLookup对散列大型数据集非常有用。 –

+0

我更喜欢SQL连接而不是查找。价值表是巨大的,每天都在增长。 –