首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场

多列组By
EN

Stack Overflow用户
提问于 2015-11-11 15:21:42
回答 3查看 413关注 0票数 2

表中有如下所示的数据

RowId =11-11 08:50:48.243 2 A 2015-11- 08:51:01.433 3 B 2015-11-08:51:01.433 3 B 2015:11-11 08:50:48.243 2 A

试图按以下方式获取数据:

用户,日期,计数A 2015-11-11 2B 2015-11-11 1选择用户,日期,计数(用户)从Table1组按用户,日期

因为时间涉及到日期字段,所以它会返回我3行。如何在SQL和Linq中实现这一点。请给我建议。

编辑:

我可以在SQL中得到它。

从Table1组中按用户选择用户、强制转换(日期为日期)、计数(用户)、强制转换(日期为日期)

编辑:

添加linq查询

var details = db.table1.GroupBy( r => new { r.RowId,r.User,r.Date}) .Select(g => new {Name = g.Key,Count = g.Count()}).ToList();

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-11-11 16:03:54

对于Linq查询,只需执行以下操作:(您需要使用System.Data.Entity.SqlServer命名空间导入。

执行这个linq查询所有的计算都是在服务器数据库上完成的。注意,Table1s代表Table1DbSetcontext是您的DbContext实例。

代码语言:javascript
运行
复制
var query = from item in context.Table1s
    group item by new
    {
       item.User, 
       Year = SqlFunctions.DatePart("yyyy", item.Date), 
       Month = SqlFunctions.DatePart("mm", item.Date), 
       Day = SqlFunctions.DatePart("dd", item.Date)
    } into g
    select new { g.Key.User, g.Key.Year, g.Key.Month, g.Key.Day, Count = g.Count() };

然后创建最后的结果如下:

代码语言:javascript
运行
复制
var result = query.ToList().Select(p =>
    new
    {
        p.User,
        Date = new DateTime(p.Year.Value, p.Month.Value, p.Day.Value),
        p.Count
    }).ToList();

其他解决方案是创建一个DbContext将用于检索所需数据的SQL。SQL视图主体必须是您在问题中所写的SQL。

编辑2: DbFunctions

就像Cetin在注释中指出的那样,我们也可以使用System.Data.Entity.DbFunctions。而且代码比使用SqlFunctions.更干净。这将只适用于EF 6和更高版本。使用SqlFunctions的版本适用于EF 4和更高版本。

代码语言:javascript
运行
复制
var query = from item in context.Table1s
    group item by new
    {
        item.User, 
        Date = DbFunctions.TruncateTime(item.Date)
    } into g
    select new { g.Key.User, g.Key.Date, Count = g.Count() };

编辑1:这是特定于Cetin Basoz的回答:

众所周知,使用AsEnumerable并不能有效地完成所需的工作。他给我们的第二个解决办法是:

代码语言:javascript
运行
复制
var grouped = from d in db.MyTable
          group d by new {
  User = d.User, 
  Date=d.Date.HasValue ? d.Date.Value.Date : (DateTime?)null} into g
  select new {User=g.Key.User, Date=g.Key.Date, Count=g.Count()};

此解决方案只是不起作用,因为:

LINQ实体中不支持指定类型成员“Date”。只支持初始化器、实体成员和实体导航属性。

票数 0
EN

Stack Overflow用户

发布于 2015-11-11 15:29:03

如果时间是问题所在,您可以首先转换它:

代码语言:javascript
运行
复制
select User, CAST(dateColumn AS DATE) as dateConverted
into #tempTable
from myTable

然后通过以下方式使用窗口函数或组:

代码语言:javascript
运行
复制
select *,
    count(user) over (partition by date) as userCount
    from #tempTable

这应该适用于SQL服务器,不知道Linq

编辑:如果日期部分是问题,只需select into从您的表到一个表的铸造日期。那么在Linq就不会有这个问题了。

票数 0
EN

Stack Overflow用户

发布于 2015-11-11 15:45:44

代码语言:javascript
运行
复制
var grouped = from d in db.MyTable.AsEnumerable()
              group d by new {
      User = d.User, 
      Date=d.Date.HasValue ? d.Date.Value.Date : (DateTime?)null} into g
              select new {User=g.Key.User, Date=g.Key.Date, Count=g.Count()};

迟早有人会说,这不是服务器端分组,会受到性能的影响,而且他们是对的。如果没有可枚举的,则它是服务器端的,但代价是每个组的另一个调用,因此这里有另一种方法:

代码语言:javascript
运行
复制
public class MyResult
{
  public string User {get;set;}
  public DateTime? Date {get;set;}
  public int Count {get;set;}
}

var grouped = db.ExecuteQuery<MyResult>(@"select [User], 
  Cast([Date] as Date) as [Date],
  Count(*) as [Count]
from myTable
group by [user], Cast([Date] as Date)");

编辑:我不知道为什么以前我想的是另一种方式,这只会在服务器端工作,而不需要AsEnumerable():

代码语言:javascript
运行
复制
var grouped = from d in db.MyTable
              group d by new {
      User = d.User, 
      Date=d.Date.HasValue ? d.Date.Value.Date : (DateTime?)null} into g
  select new {User=g.Key.User, Date=g.Key.Date, Count=g.Count()};
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33653762

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档