保留中间数据表列值并删除其他值

时间:2015-10-10 23:47:34

标签: c# datatable

也许标题不是很明确,但样本图像很容易理解我需要的东西。

我有一个DataTable C#,其中包含以下列:

enter image description here

我想只保留一个" 类别"按行" 类别"

的总行数中间非常接近的值

这是我想要完成的一个例子。

enter image description here

  

感谢任何帮助。

3 个答案:

答案 0 :(得分:0)

我可以解决它。

以下是代码,可能不是最优雅的解决方案,但可行。

List<int> rowIndexes = new List<int>();

                    DataView viewCategories = new DataView(ds.Tables["data"]);
                    DataTable dtCategories = viewCategories.ToTable(true, "categorytype");

                    // format datatable
                    for(int rowIndex = 0; rowIndex < ds.Tables["data"].Rows.Count; rowIndex++)
                    {
                        DataRow dr = ds.Tables["data"].Rows[rowIndex];

                        if (rowIndex < ds.Tables["data"].Rows.Count - 1)
                        {
                            DataRow drNext = ds.Tables["data"].Rows[rowIndex + 1];

                            if (dr["categorytype"].ToString() != drNext["categorytype"].ToString())
                            {
                                rowIndexes.Add(rowIndex);
                            }
                        }   
                    }

                    int index = 0;
                    // insert empty rows
                    foreach(int rowIndex in rowIndexes)
                    {
                        index++;

                        DataRow newRow = ds.Tables["data"].NewRow();

                        ds.Tables["data"].Rows.InsertAt(newRow, rowIndex + index);
                        ds.Tables["data"].AcceptChanges();
                    }


                    // clean categories and keep only one
                    foreach (DataRow dr in dtCategories.Rows)
                    {
                        DataView view = ds.Tables["data"].DefaultView;
                        view.RowFilter = "categorytype = '" + dr["categorytype"].ToString() + "'";

                        if (view.Count > 1)
                        {
                            int mid = (int)Math.Floor((double)view.Count / (double)2);

                            index = 0;

                            foreach(DataRowView drView in view)
                            {
                                if (index != mid) drView["categorytype"] = string.Empty;
                                index++;
                            }


                            ds.Tables["data"].AcceptChanges();


                        }
                    }

答案 1 :(得分:0)

我没有足够的代表来提问,因此,在不知道您要尝试实现的UI输出的情况下,例如datagrid,或Razor,或Excel等 - 您可以使用应包含类别名称的行号在SQL中填充数据表,如下所示:

&#13;
&#13;
  select category,invoice,amount,tax,total, 0 as ccount into #temp from test
  update #temp set ccount = (select round(cast(count(category) as decimal)/2.0,0) from test where category=#temp.category group by test.category)

  select * from #temp
  drop table #temp
&#13;
&#13;
&#13;

这将为您提供结果数据表:

enter image description here

然后,当您遍历行时,如果行号匹配&#34; ccount&#34;,则打印类别名称。

答案 2 :(得分:0)

//dt is DataTable
foreach (var category in dt.AsEnumerable().GroupBy(g => g.Field<string>("Category")))
{
    var rows = category.OrderBy(o => o.Field<int>("Invoice")).ToArray();
    foreach (DataRow row in rows.Where((w, i) => i != (rows.Length-1) / 2))
    {
        row["Category"] = "";
    }
}

或SQL如果可以使用

SELECT CASE WHEN 
ROW_NUMBER() OVER (PARTITION BY Category ORDER BY Invoice) 
= ((COUNT(*) OVER (PARTITION BY Category)+1)/2)  
THEN Category ELSE '' END,
Invoice, Amount, Tax, Total
FROM DataTable
ORDER BY Invoice