Group By with multiple column

时间:2015-11-11 15:21:43

标签: c# sql linq

我在表格中有数据如下

class FITString{
    char *tekst;
public: 
    FITString(char *bla = " "){
        tekst = new char[strlen(bla) + 1];
        strcpy_s(tekst, strlen(bla) + 1, bla);
    }
    ~FITString(){
        delete[] tekst;
        tekst = nullptr;        
    }
    FITString(FITString &original){
        tekst = new char[strlen(original.tekst) + 1];
        strcpy_s(tekst, strlen(original.tekst) + 1, original.tekst);
    }
    FITString operator+ (FITString &drugi){
        char *pomocna = new char[strlen(tekst) + strlen(drugi.tekst) + 1];
        strcpy_s(pomocna, strlen(tekst) + 1, tekst);
        strcat_s(pomocna, strlen(tekst) + strlen(drugi.tekst) + 1, drugi.tekst);
        return pomocna;
    }

    void operator+= (FITString &drugi){
        strcat_s(tekst, strlen(tekst) + strlen(drugi.tekst) + 1, drugi.tekst);      
    }

    char & operator[] (int position){
        char *pomocni = new char[strlen(tekst)+1];
        strcpy_s(pomocni, strlen(tekst) + 1, tekst);
        if (position <= strlen(tekst)){
            pomocni += position;
            pomocni--;
            return *pomocni;
        }
    }

    friend ostream & operator<< (ostream &COUT, FITString &obj);

};


ostream & operator<< (ostream &COUT, FITString &obj){
    COUT << obj.tekst;
    return COUT;
}

int main()
{
    FITString bezze = "Sta ima";
    FITString bezze2 = "Nema nista";
    FITString bezze3 = "Ma eo";
    FITString bezze4 = bezze + bezze2 + bezze3;
    cout << bezze4 << endl;
    FITString bezze5 = "Ma jok";
    cout << endl;

    bezze5 += bezze;
    cout << bezze5 << endl;
    cout << bezze5[4] << endl;
    system("Pause");
    return 0;
}

尝试获取如下数据:

RowId | User | Date 
--------------------------
  1     A     2015-11-11 08:50:48.243
  2     A     2015-11-11 08:51:01.433
  3     B     2015-11-11 08:51:05.210

由于Date字段中涉及的时间,它返回了3行。 如何在SQL和Linq中获得它。 请建议我。

编辑:

我能够在SQL中获取它

User, Date,        Count
  A   2015-11-11     2
  B   2015-11-11     1

 Select User,Date,Count(User) from Table1 
 Group By User,Date

编辑:

添加linq查询

 Select User,Cast(Date as Date),Count(User) from Table1 
 Group By User,Cast(Date as Date)    

3 个答案:

答案 0 :(得分:0)

如果时间有问题,您可以先转换它:

select User, CAST(dateColumn AS DATE) as dateConverted
into #tempTable
from myTable

然后使用窗口函数或组:

select *,
    count(user) over (partition by date) as userCount
    from #tempTable

这应该适用于SQL Server,不了解Linq

编辑:如果日期部分是问题,只需从表中select into到具有投放日期的表。然后你在Linq中遇到了这个问题。

答案 1 :(得分:0)

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

迟早,有人会说这不是服务器端分组,会受到性能的影响而且会是正确的。没有Enumerable,它是服务器端,但代价是每个组的另一个呼叫,所以这是另一种方式:

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():

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

答案 2 :(得分:0)

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

执行此linq查询所有计算都在服务器数据库上完成。请注意,Table1s代表DbSet的{​​{1}},Table1代表context实例。

DbContext

然后像这样创建最终结果:

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

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

编辑2:DbFunctions

与Cetin Basoz一样,我们也可以使用 System.Data.Entity.DbFunctions 。代码比使用 SqlFunctions 更清晰。这仅适用于EF 6及更高版本。使用SqlFunctions的版本适用于EF 4及更高版本。

var result = query.ToList().Select(p =>
    new
    {
        p.User,
        Date = new DateTime(p.Year.Value, p.Month.Value, p.Day.Value),
        p.Count
    }).ToList();

编辑1:这是特别针对Cetin Basoz的回答:

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

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

这个解决方案因为这个原因而无效:

  

LINQ to Entities不支持指定的类型成员“Date”。仅支持初始化程序,实体成员和实体导航属性。