【问题标题】:return items that all records related to that items have specific conditions返回与该项目相关的所有记录都具有特定条件的项目
【发布时间】:2012-07-17 05:16:02
【问题描述】:

请考虑这种情况:

我有一张这样的桌子:

ID              City            Status
--------------------------------------
 1               1                1
 2               1                1
 3               1                1
 4               2                1
 5               2                0
 6               3                1
 7               3                1
 8               3                1
 9               3                1
 10              4                3
 11              4                1
 12              4                0

我想返回 Citis,所有与该城市相关的记录都有 Status=1,如果其中一条记录有 Status<>1,则该城市从 reslut 集中排除。在这种情况下,我想返回城市:1、3。

如何使用 Sql Query 或 LINQ 查询来做到这一点?

谢谢

【问题讨论】:

    标签: c# sql sql-server linq entity-framework


    【解决方案1】:

    应该这样做。

    LINQ:

    var citiesToExclude = context.Table
        .Where(t => t.Status != 1)
        .Select(t => t.City);
    var cities = context.Table
        .Where(t => t.Status == 1)
        .Where(t => !citiesToExclude.Contains(t.City))
        .Select(t => t.City)
        .Distinct()
        .ToList();
    

    SQL:

    SELECT City
    FROM [Table]
    WHERE Status == 1
      AND City NOT IN (SELECT City FROM [Table] WHERE Status <> 1)
    GROUP BY City
    

    希望这会有所帮助。

    【讨论】:

    • 谢谢@Maarten:你能用linq写下你的Lamdba版本吗?我写了这个:var citiesToExclude = from r in ent.TestAllStatusEqualsOnes where r.Status != 1 select new { r.City }; var cities = (from r in ent.TestAllStatusEqualsOnes where r.Status == 1 &amp;&amp; citiesToExclude.Contains(r.City) == false select new { r.City }).Distinct().ToList(); 但它没有用
    • 出了什么问题?我的版本是 lambda 版本恕我直言。
    • @Kerezo new { r.City } 当你想要的只是一个整数时创建一个匿名对象。要解决此问题,请将 new { r.City } 替换为 r.City。这应该使您的查询语法解决方案像 Maarten 的方法语法解决方案一样工作。
    【解决方案2】:

    您可以简单地将GROUP BYHAVING 与条件聚合一起使用:

    SELECT   city
    FROM     tbl
    GROUP BY city
    HAVING   COUNT(CASE WHEN status <> 1 THEN 1 END) = 0
    

    【讨论】:

    • 你能写出linq版本吗。
    • 这不会检查城市是否有状态 = 1 的记录。如果一个城市有状态 = 0 的记录和另一个状态 = NULL 的记录,这可能会导致错误。
    • @Maarten,OP 没有指定是否允许状态列包含 NULL 值。如果不允许,则无需检查是否为status=1,否则,我们只需在CASE 表达式中添加OR status IS NULL
    • @Kerezo:不幸的是,我不熟悉 LINQ。但是,我相信这是迄今为止提供的最有效的解决方案(避免使用子查询、子选择、连接等),所以也许知道 LINQ 的人可以翻译它。
    【解决方案3】:

    另一种方式

    select distinct city 
    from city C1
     where city=1 and not exists(select * from city C2 where C1.city=C2.city 
     and isnull(Status,0)<>1)
    

    【讨论】:

    • 这不会检查城市是否有状态 = 1 的记录。如果一个城市有状态 = 0 的记录和另一个状态 = NULL 的记录,这可能会导致错误。
    【解决方案4】:
    SELECT tbl.city
    FROM 
    (SELECT c.city, count(status=1) cnt1, count() cnt2
    FROM city c
    GROUP BY c.city) AS tbl
    WHERE tbl.cnt1=tbl.cnt2 AND tbl.cnt1>0
    

    【讨论】:

      【解决方案5】:

      这看起来像是 LINQ 的 group 子句的工作:

      var cities = from t in table
                   group t by t.City into grp
                   where grp.Select(g => g.Status).All(s => s == 1)
                   select g.Key;
      

      【讨论】:

        【解决方案6】:

        你为什么不能用这个?该函数似乎没有聚合,因此不需要having

        select city 
        from [table]
        where status = 1
        and city not in 
        (select city from table where status <> 1)
        group by city;
        

        除非我误解了这个问题?

        【讨论】:

        • 错过了 Q 的那一部分,乔。这现在可以工作了,对吧?
        猜你喜欢
        • 2013-08-29
        • 2023-03-12
        • 1970-01-01
        • 2016-02-09
        • 1970-01-01
        • 2022-08-03
        • 2022-12-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多