如何只选择一列中具有唯一值的行?

时间:2012-08-25 21:40:17

标签: c# linq-to-sql distinct

考虑这个示例数据:

field1  field2  
1       100  
2       100  
3       101  
4       102  
5       102  
6       103   

我想只选择field2中的值只出现一次的记录。上述所需返回数据的一个例子是:

field1  field2  
3       101  
6       103   

如何使用LINQ to SQL完成这项工作?

---编辑-------
大家好,谢谢你的回复。我故意提供简化数据以正确解决我的问题的根源。我认为所有这些答案都会根据我的示例数据返回所需的结果,我会将它们标记为所有答案。

然而,在我的真实数据场景中,使用我从您的回复中学到的东西,我有类似的东西:

var RefinedSource =  from a in dSource
                     group a by a.AssetID into g
                     where g.Count() == 1
                     select new
                     {
                          AssetID = g.Key,
                          AssetType = g.Min(a => a.AssetType),
                          IPInfo = AppUtility.GetIPInfo(g.Key),
                          Hostname = AppUtility.GetServerName(g.Key),
                          DeviceID = g.Min(a => a.DeviceID).ToString(),
                          Environment = AppUtility.GetSolutionAndEnvironmentNames(g.Key),
                          Manufacturer = g.Min(a => a.Manufacturer),
                          MakeModel = g.Min(a => a.MakeModel),
                          Location = g.Min(a => a.Location),
                          count = g.Count()
                     };

所以我担心所有.min()调用......我推断这些是必要的,因为分组?有人可以解释为什么需要这些吗?在我的简单示例的情况下,我不认为它们是一个问题,但是我的真实数据有多次调用min()只是为了能够包含我需要的所有字段数据...这似乎不是好。

分组允许我测试我需要的条件(用于识别重复值的计数),但是如何更直接地使用这样的条件,但只是直接访问我真实的底层数据行?

例如,看一下我上面提供的示例,我希望能够使用原始“来自in dSource”部分的a.FieldName,但是在引入之后你无法访问它。通过...分组”?

再次感谢信息,我将标记为答案,但是如果有人能解释所有对min()(或者max,或者其他)的所有调用的需要,我会很感激,同时,看看它的样子和我的真实数据一样,这仍然是我应该去的方式吗?

3 个答案:

答案 0 :(得分:1)

以下是如何在SQL中完成的(有时使用SQL会更快):

 SELECT max(field1), field2
 FROM table
 GROUP BY field2
 HAVING count(field2) = 1

在sql server中使用窗口函数的示例
(注意,现在无法测试OVER子句可能需要在哪里):

 SELECT COUNT() OVER(PARTITION BY field2) AS [field2Count], *
 FROM table
 WHERE [field2Count] = 1 

答案 1 :(得分:1)

from r in tables
  group r.field2 by r.field1 into grp
  where grp.Count() == 1
  select new {grp.First(), grp.Key}

我会仔细检查这是否会进行一次SQL调用。它应该,如果是这样的话,我会把它保留在这里,因为First是一种非常常用的Linq方法,当在给定的情况下有几十个同样好的东西时,人们应该喜欢熟悉的。如果它确实导致多个SQL调用(再次,我会感到惊讶),那么请尝试Max()Min()而不是First()

答案 2 :(得分:0)

使用LINQ,您可以做到:

var groups = list.GroupBy(r => r.Value).Where(grp => grp.Count() == 1);

foreach(var gr in groups){
   var field1 = gr.Key;      // KEY: is your FIELD1
   var field2 = gr.Value;    // VALUE: is your FIELD2
}