如何在 DataTable.Select(Expression) 中使用 SELECT GROUP BY?

Posted

技术标签:

【中文标题】如何在 DataTable.Select(Expression) 中使用 SELECT GROUP BY?【英文标题】:How do I use SELECT GROUP BY in DataTable.Select(Expression)? 【发布时间】:2013-10-24 19:14:42 【问题描述】:

我尝试通过从每个组中选择第一行来删除重复的行。 例如

PK     Col1     Col2
1        A        B
2        A        B
3        C        C
4        C        C

我要退货:

PK     Col1     Col2
1        A        B
3        C        C

我尝试了以下代码,但没有成功:

DataTable dt = GetSampleDataTable(); //Get the table above.
dt = dt.Select("SELECT MIN(PK), Col1, Col2 GROUP BY Col1, Col2);

【问题讨论】:

你不能。请改用 LINQ。 不能按PK字段分组... 我想使用什么,但我想返回一个 DataTable 对象。 为什么不将分组或其他复杂处理委托给数据库级别的 sql,这样会更自然 这能回答你的问题吗? Efficient DataTable Group By 【参考方案1】:

DataTableSelect方法只支持field = value这样的简单过滤表达式。它不支持复杂的表达式,更不用说 SQL/Linq 语句了。

但是,您可以使用 Linq 扩展方法提取 DataRows 的集合,然后创建一个 DataTable

dt = dt.AsEnumerable()
       .GroupBy(r => new Col1 = r["Col1"], Col2 = r["Col2"])
       .Select(g => g.OrderBy(r => r["PK"]).First())
       .CopyToDataTable();

【讨论】:

您需要使用什么程序集引用才能使其正常工作。我正在使用 System.data 但 GroupBy 命令说明我缺少程序集引用。 这个 .CopyToDataTable() 是什么扩展名? @SebastianWidz System.Data.DataSetExtensions @user5013 GroupBy 在 System.Linq 命名空间中。如果您还没有System.Core,则需要参考。【参考方案2】:
dt = dt.AsEnumerable().GroupBy(r => r.Field<int>("ID")).Select(g => g.First()).CopyToDataTable();

【讨论】:

这个 .CopyToDataTable() 是什么扩展名?【参考方案3】:
dt.AsEnumerable()
    .GroupBy(r => new  Col1 = r["Col1"], Col2 = r["Col2"] )
    .Select(g =>
    
        var row = dt.NewRow();

        row["PK"] = g.Min(r => r.Field<int>("PK"));
        row["Col1"] = g.Key.Col1;
        row["Col2"] = g.Key.Col2;

        return row;

    )
    .CopyToDataTable();

【讨论】:

【参考方案4】:

此解决方案按 Col1 排序并按 Col2 分组。然后提取 Col2 的值并显示在 mbox 中。

var grouped = from DataRow dr in dt.Rows orderby dr["Col1"] group dr by dr["Col2"];
string x = "";
foreach (var k in grouped) x += (string)(k.ElementAt(0)["Col2"]) + Environment.NewLine;
MessageBox.Show(x);

【讨论】:

【参考方案5】:

基于@Alfred Wallace 的解决方案:

        DataTable dt = new DataTable();
        dt.Columns.Add("Col1");
        dt.Columns.Add("Col2");

        dt.Rows.Add("120", "34");
        dt.Rows.Add("121", "34");
        dt.Rows.Add("122", "34");

        dt.Rows.Add("1", "345");
        dt.Rows.Add("2", "345");
        dt.Rows.Add("3", "345");

        var grouped = from DataRow dr in dt.Rows orderby dr["Col1"] group dr by dr["Col2"];
        string xxx = "", yyy = "";
        foreach (var k_group in grouped)
                        
            xxx += (string)(k_group.ElementAt(0)["Col1"]) + Environment.NewLine;
            foreach (DataRow item_dr in k_group)
                                
                yyy += (string)(item_dr["Col1"]) + Environment.NewLine;
                //  or use WhatEverMethod(item_dr);
            
            var zzz = k_group.Max(g => g["Col1"]);
            var qqq = k_group.Key;
        

【讨论】:

以上是关于如何在 DataTable.Select(Expression) 中使用 SELECT GROUP BY?的主要内容,如果未能解决你的问题,请参考以下文章

c# datatable select问题

如何将 DataTable.Select() 的结果绑定到 ListBox 控件?

我们可以在 c# 中的 datatable.select 中添加参数吗

项目中遇到的 linq datatable select

在DataTable中执行DataTable.Select("条件"),

我如何知道DataTable当前是第几行