【问题标题】:How to calculate amount of records that meet and don't meet criteria如何计算符合和不符合条件的记录数量
【发布时间】:2012-04-20 12:35:03
【问题描述】:

我想计算拥有所有者 (OwnerId!=0) 和没有所有者 (OwnerId==0) 的团队数量。

在普通 SQL 中,我会使用一个查询,只使用 2 个子查询:

select
    (SELECT COUNT(*) FROM teams WHERE User=0) AS FreeTeams,
    (SELECT COUNT(*) FROM teams WHERE User!=0) AS UsedTeams

他们有更简单的方法吗?如何将其翻译成 Linq2Sql?

谢谢。

【问题讨论】:

    标签: .net sql linq-to-sql


    【解决方案1】:
    var sums =
     (from t in teams
     group t by 0 into g
     select new { freeTeams = g.Count(p => p.User == 0), usedTeams = g.Count(p => p.User != 0) }).SingleOrDefault();
    

    这将只发出一个查询,但需要两次表扫描,因为 L2S 无法有效地转换它。

    我们可以将其归结为一次表扫描:

    var sums =
     (from t in teams
     group t by (t.User != 0) into g
     select new { isUsedTeam = g.Key, Count = g.Count() }).ToList();
    

    这将为您提供两行,一排用于 freeTeams,另一排用于 usedTeams。 令人讨厌,但 LINQ2SQL 可用的最快方法。

    【讨论】:

      【解决方案2】:

      在普通 SQL 中,更简单的方法是使用 CASE 语句:

      SELECT SUM(CASE WHEN [User]=0 THEN 1 ELSE 0 END) AS FreeTeams,
             SUM(CASE WHEN [User]<>0 THEN 1 ELSE 0 END) AS UsedTeams
      FROM Teams
      

      【讨论】:

        【解决方案3】:

        假设您的 teams 对象设置正确,您可以像这样在 Linq to SQL 中执行此操作:

        var freeTeams = teams.Count(p => p.User == 0);
        var usedTeams = teams.Count(p => p.User != 0);
        

        如果你真的想对数据库进行一次点击,并且愿意牺牲一些可读性,你可以使用这样的东西:

        var counts = from a in teams
            group a by true into aa
            select new
            {
                freeTeams = aa.Count(p => p.User == 0),
                usedTeams = aa.Count(p => p.User != 0)
            };
        

        【讨论】:

        • 这将执行两个 SQL 批处理。效率有点低。
        • @usr 考虑到您需要跳过这些障碍才能将其转换为 LINQ to SQL 中的单个查询,我将在任何一天都采取微小的额外打击来提高可读性。除非有人知道一种我不知道的干净的写法,这是很有可能的。
        • 是的。不过,我已经添加了答案。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-02-09
        • 2014-08-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多