【问题标题】:LEFT JOIN CTE as Lambda Expression / Query ExpressionLEFT JOIN CTE 作为 Lambda 表达式/查询表达式
【发布时间】:2013-11-03 00:11:30
【问题描述】:

如何将以下 SQL 查询(CTE LEFT JOINED 与另一个表)编写为 Lambda 或查询表达式?

WITH Hours as
(
    SELECT 0 As Hour
    UNION ALL
    SELECT Hour + 1
    FROM Hours
    WHERE Hour + 1 < 24
)
SELECT Hours.Hour, COALESCE(Revenue, 0) FROM Hours 
LEFT JOIN
(
SELECT DATEPART(hh, TableDate) As Hour, SUM(Revenue) Revenue FROM MyTable 
GROUP BY DATEPART(hh, TableDate)
) c
ON 
c.Hour = Hours.Hour

我知道我可以 GroupJoin 和 SelectMany 来完成 LEFT JOIN,但我不知道从哪里开始表示查询的 CTE 部分。我是否只需要创建一个静态表来使用 lambda 或查询表达式完成此操作?

-- 编辑--

所以我最终得到了这个(为了便于阅读,我更喜欢查询表达式而不是 lambda):

    var revenue = (
                   from range in Enumerable.Range(0, 23)
                   join conv in db.MyTable on range equals conv.TableDate.Hour into c
                   from d in c.DefaultIfEmpty()
                   group d by range into g
                   select new { Hour = g.Key, Revenue = g.Sum(e => e == null ? 0.0 : e.Revenue), }
                  )

【问题讨论】:

  • 我宁愿担心公用表表达式(WITH 部分)。但无论如何,您是否已经尝试过任何东西并且可以分享您编写的任何代码?
  • 我应该将我的问题编辑得更具体。 CTE 正是我遇到困难的查询部分。事实上,我不知道从哪里开始。我知道我可以在派生的 Hour 列上使用 GroupJoin 后跟 SelectMany 完成 LEFT JOIN。但我不知道如何指定 CTE。我是否只需要创建一个静态表来代替 CTE?
  • 看我的回答杰夫你使用范围来生成数字

标签: c# sql sql-server lambda


【解决方案1】:

很难准确地说出您的模型在 linq 中会是什么,但可能是这样的:

var Enumerable.Range(0,23)
      .Join(MyTable.GroupBy(x => x.TableDate.Hour())
             .Select(g => new { hour = g.Key, rev = g.Revenue.Sum() },
            h => h,
            g => g.hour,
            (h , g) -> new { hour = h, revenue = g.rev });

【讨论】:

  • 我很确定它不会生成 CTE SQL,但我认为它可能会起作用!真的很好的答案!
  • 我从没想过使用 Enumerable.Range。我现在就试试。
  • @MarcinJuraszek - 为什么我希望它生成 CTE?
  • @Jeff - 这就是 CTE 正在做的事情......创建一个值 0 到 23 的表(与 linq 中的可枚举相同)。
  • @Hogan 来自问题的源 SQL 使用 CTE :) 但只要它返回相同的结果,那就太好了!
【解决方案2】:

等效的 linq 查询表达式

from a in Enumerable.Range(0, 24)
join b in Mytables on a equals b.TableDate.Hour into c
from d in c.DefaultIfEmpty()
group d by a into g
select new {h = g.Key, s = g.Sum(e => e == null ? 0.0m : e.Revenue)}

【讨论】:

  • 谢谢 - 我需要使用它来提高可读性。只有需要的可枚举范围只有 (0, 23),因为没有 TableDate.Hour 可以转换为 24。
  • @Jeff Enumerable.Range 的第二个参数是计数,而不是终点。你想要 24 岁。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多