也许标题不是很明确,但样本图像很容易理解我需要的东西。
我有一个DataTable
C#,其中包含以下列:
我想只保留一个" 类别"按行" 类别"
的总行数中间非常接近的值这是我想要完成的一个例子。
感谢任何帮助。
答案 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中填充数据表,如下所示:
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;
这将为您提供结果数据表:
然后,当您遍历行时,如果行号匹配&#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