2011-08-24 56 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連接而不是查找。價值表是巨大的,每天都在增長。 –