Linq 查询:MAX in WHERE

发布于 2024-12-01 01:25:17 字数 691 浏览 0 评论 0原文

我有一个很长的查询,返回

Item {
    DateTime entryDate
    .....
}

我喜欢将此查询的结果与另一个表结合起来

Value {
    DateTime date,
    double value
}

,这样如果entryDate >= CUTOFF,则取CUTOFF上的值,否则取entryDate上的值。换句话说,我想实现:

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

请原谅我的语法,但这就是想法。

编辑:经过一番试验和错误,我想出了这个 linq-to-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    
}

感谢您的帮助。

I have a long query that returns

Item {
    DateTime entryDate
    .....
}

I like to combine the result of this query with another table

Value {
    DateTime date,
    double value
}

such that if entryDate >= CUTOFF, then take the value on CUTOFF, else take the value on entryDate. In other words, I'd want to achieve:

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

Excuse my syntax, but that's the idea.

EDIT: After some trial and error, I came up with this linq-to-sql query:

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    
}

Thanks for your help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

烟─花易冷 2024-12-08 01:25:17
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
                              });

过滤查询,将两项合并为一项并修改第一项

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
                              });

Filter the query, Combine the two items into one item and modify the first item

关于从前 2024-12-08 01:25:17

鉴于您已从 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 扩展非常有用,但经常被忽视。

Given that you've returned your data from your Item query and that the Value table is relatively small then this is a nice way to go:

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,
    };

The ToLookup extension is very useful and often overlooked.

叶落知秋 2024-12-08 01:25:17

如果entryDate >= CUTOFF,则取CUTOFF上的值,否则
取entryDate 上的值。换句话说,我想实现:
选择 Item.*, Value.value WHERE MAX( Item.entryDate, CUTOFF ) ==
值.日期

这是矛盾的 - if entryDate >= CUTOFF then take the value on CUTOFF 意味着您想要 MIN(Item.entryDate, CUTOFF),而不是 最大

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

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

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


如果您需要将其作为单个 SQL 语句执行,则需要进行一些重构。一个好的开始是将 matchingValue 交换到单个语句中。

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

我面前没有 Visual Studio 来确认,但我不确定 Math.Min 函数是否已映射到 LINQ-to-SQL 中。我们假设事实并非如此。

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

我相信,如果您使用 .ToList() 执行它,它将解析为单个查询,但在我面前有一些工具之前无法确认。使用 SQL 探查器对其进行测试以确定。

such that if entryDate >= CUTOFF, then take the value on CUTOFF, else
take the value on entryDate. In other words, I'd want to achieve:
SELECT Item.*, Value.value WHERE MAX( Item.entryDate, CUTOFF ) ==
Value.date

This is contradictory - if entryDate >= CUTOFF then take the value on CUTOFF imples that you want MIN(Item.entryDate, CUTOFF), not MAX.

Having said that, you just want to select the value.Value that matches each item of your query. Each item should look up the relevant value which matches your MAX (or, I believe, MIN) statement.

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

This will return an IQueryable of anonymous { Item, double } objects.


If you require this to be a executed as a single SQL statement you'll need to do some refactoring. A good start is to swap matchingValue into a single statement.

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

I don't have a Visual Studio in front of me to confirm, but I am not sure that the Math.Min function is mapped in LINQ-to-SQL. Let's assume it's not.

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

I believe that will resolve to a single query if you execute it with a .ToList() but can't confirm until I have some tools in front of me. Test it with SQL profiler to be sure.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文