C# DataTable重新排列组合问题

l25926845 2015-11-13 06:25:15
已知在数据库中使用存储过程查询到如下表

注意图中黄色部分的二三四列都是一样的,只是后面送货日期不一样。
要求重新组合成如下样式:

可以看到,蓝色部分的两行合并了。
​绿色部分添加和横向总想的求和

求实现方法或者思路,如果能直接在数据库中使用存储过程完成也可以。

谢谢
...全文
265 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
wfy4422 2015-11-16
  • 打赏
  • 举报
回复
存储过程里用查询拼接字符串的方法,既然你能查出后面不固定列,加group by 应该也不是难事吧?也可以处理Datatable,我做过类似的问题,前面固定的列你可以作为分组依据嘛,可以用linq,也可以用DataTble.ToTable。然后创建另外一个相同架构Datable,即用Clone(),每一组,循环将分组键值及非固定列的值插入去
  • 打赏
  • 举报
回复
select sum(日期), 其他字段 from table group by prochDOc, meterail 用输出参数返回总数,或者返回两个结果集,用dataSet接收 select @total1 = sum(日期), @ total2 = sum(日期)... from table
xdashewan 2015-11-16
  • 打赏
  • 举报
回复
引用 7 楼 l25926845 的回复:
感觉可以在上面代码前先合并?
完全可以在'SELECT * FROM tPo2 PIVOT (SUM(GRQty2) FOR delDate IN ('+@sql+')) a WHERE vendor = '+ '50002903'这句sql外面再套一层用于合并的group by
l25926845 2015-11-16
  • 打赏
  • 举报
回复
引用 6 楼 xdashewan 的回复:
[quote=引用 5 楼 l25926845 的回复:]
根据这个vender查到的结果就是这样的,其中8-10条数据前面都一样,但对应多个送货日期就需要合并了。
不知道这样用您的方法是否还可行?

数据库里直接MAX后面几个字段,group by你应该会的吧[/quote]
上图的结果其实是在SQL中查询出来的

我用了一个存储过程vendor作为变量,将日期作为列名移到了上面
DECLARE @sql VARCHAR(8000)

SELECT @Sql=ISNULL(@sql+',','')+'['+delDate+']' FROM tPo2
WHERE vendor = '50002903'
GROUP BY delDate
ORDER BY delDate DESC

SET @sql='SELECT * FROM tPo2 PIVOT (SUM(GRQty2) FOR delDate IN ('+@sql+')) a WHERE vendor = '+ '50002903'
EXEC (@sql)


原表是这样的


感觉可以在上面代码前先合并?
xdashewan 2015-11-16
  • 打赏
  • 举报
回复
引用 5 楼 l25926845 的回复:
根据这个vender查到的结果就是这样的,其中8-10条数据前面都一样,但对应多个送货日期就需要合并了。 不知道这样用您的方法是否还可行?
数据库里直接MAX后面几个字段,group by你应该会的吧
l25926845 2015-11-16
  • 打赏
  • 举报
回复
引用 3 楼 shingoscar 的回复:
你需要建立一张hashtable,它的key是前4个字段,value是后3个字段
随后遍历数据表,如果某条记录的前4个字段在hashtable中已经存在,就合并。

引用 3 楼 shingoscar 的回复:
你需要建立一张hashtable,它的key是前4个字段,value是后3个字段
随后遍历数据表,如果某条记录的前4个字段在hashtable中已经存在,就合并。

你好,可能我说的有问题。第一张图中只有前几列是固定的,后面的送货日期不一定,有可能是三列也有可能是很多列。
如下图:

根据这个vender查到的结果就是这样的,其中8-10条数据前面都一样,但对应多个送货日期就需要合并了。
不知道这样用您的方法是否还可行?
Poopaye 2015-11-16
  • 打赏
  • 举报
回复
大概写了下 结构
class Key
{
	public string vendor;
	public string purchDoc;
	public string material;
	public string shoText;

	public override int GetHashCode()
	{
		unchecked
		{
			return
				((vendor.GetHashCode() * 33 +
				purchDoc.GetHashCode()) * 33 +
				material.GetHashCode()) * 33 +
				shoText.GetHashCode();
		}
	}

	public override bool Equals(object obj)
	{
		Key other = obj as Key;
		return other != null &&
			other.vendor == this.vendor &&
			other.purchDoc == this.purchDoc &&
			other.material == this.material &&
			other.shoText == this.shoText;
	}
}

class Value
{
	public Dictionary<string, string> data;
}

Dictionary<Key, Value> table; //hashtable
转换过程
DataTable dt; //要操作的数据表

//合并过程
foreach (DataRow row in dt.Rows)
{
	Key key = new Key
	{
		vendor = (string)row["vendor"],
		purchDoc = (string)row["purchDoc"],
		material = (string)row["material"],
		shoText = (string)row["shoText"],
	};

	Value value;

	//查找
	if(!table.TryGetValue(key, out value))
	{
		value = new Value();
		table.Add(key, value);
	}

	//合并value, 5是日期开始的列号
	for (int col = 5; col < dt.Columns.Count; ++col)
	{
		if (!value.data.ContainsKey(dt.Columns[col].ColumnName) && row[col] != null)
			value.data.Add(dt.Columns[col].ColumnName, (string)row[col]);
	}
}

//写入合并后的数据
//这边可以直接写sql
foreach (var item in table)
{
	DataRow newrow = dt.NewRow();
	newrow["vender"] = item.Key.vendor;
	//...........
	foreach (var item2 in item.Value.data)
	{
		newrow[item2.Key] = item2.Value;
	}
	dt.Rows.Add(newrow);
}
xdashewan 2015-11-16
  • 打赏
  • 举报
回复
http://www.cnblogs.com/zhangzt/archive/2010/07/29/1787825.html 注意看行转列的第5个例子和之后的如何分组
l25926845 2015-11-16
  • 打赏
  • 举报
回复
引用 3 楼 shingoscar 的回复:
你需要建立一张hashtable,它的key是前4个字段,value是后3个字段 随后遍历数据表,如果某条记录的前4个字段在hashtable中已经存在,就合并。
你好,如果将前几列作为key的话,那么循环插入时肯定会报错啊 但如果反过来作为value来存储的话,有没有Contains方法
l25926845 2015-11-16
  • 打赏
  • 举报
回复
引用 8 楼 xdashewan 的回复:
[quote=引用 7 楼 l25926845 的回复:] 感觉可以在上面代码前先合并?
完全可以在'SELECT * FROM tPo2 PIVOT (SUM(GRQty2) FOR delDate IN ('+@sql+')) a WHERE vendor = '+ '50002903'这句sql外面再套一层用于合并的group by[/quote] 小弟不才,还请指教具体写法。 写了几种都会报错
l25926845 2015-11-14
  • 打赏
  • 举报
回复
感觉3L的方法可以一试
Poopaye 2015-11-13
  • 打赏
  • 举报
回复
你需要建立一张hashtable,它的key是前4个字段,value是后3个字段 随后遍历数据表,如果某条记录的前4个字段在hashtable中已经存在,就合并。
vivorimage 2015-11-13
  • 打赏
  • 举报
回复
感觉数据已经插入后做这类检查比较费时,对每一条记录都要查询其他记录是否包含与之一样的vendor、purchDoc、material和shoText属性,若表中一共有n条记录,则时间复杂度为n*n。有可能的话还是应该在插入数据时做合并。 合并过程倒直接,若使用DataTable,找到要合并的List<DataRow>,循环加就行了,遇到null就置0。
l25926845 2015-11-13
  • 打赏
  • 举报
回复
当然数据源中为null的地方也得补0

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧