所以......我有一张这样的桌子:
RowID | DocID | Time | DepartmentID
1 | 1001 | 2015-11-20 | 1
2 | 1001 | 2015-11-21 | 2
3 | 1002 | 2015-11-20 | 1
4 | 1001 | 2015-11-25 | 1
5 | 1002 | 2015-11-22 | 3
6 | 1002 | 2015-11-30 | 1
我的目标是在将部门发送给其他部门之前,花时间将部门花费在文档上。
我通过将上面的表从SQL传递到C#中的数据表来成功实现了这一点。然后获取DocsID列表,并迭代抛出该列表中的每个项目,使用DocID过滤数据表,然后计算连续行之间的时间。 所以最终结果如下:
DepartmentID | DocID | Time (Days)
1 | 1001 | 2
2 | 1001 | 5
1 | 1002 | 3
3 | 1002 | 9
问题是C#中的这个功能大约需要30秒才能得到这个结果,所以我正在寻找改进它的方法。
是否有可能只在不使用C#进行任何操作的情况下抛出SQL?
我的C#功能(dt是带有第一个表的数据表):
List<Int32> listDocIDs = new List<Int32>();
foreach (DataRow dr in dt.Rows)
{
int str = Convert.ToInt32(dr["DocID"].ToString());
if (!listDocIDs.Contains(str))
listDocIDs.Add(str);
}
DataTable times = new DataTable();
times.Columns.AddRange(new DataColumn[3] { new DataColumn("DepartmentID", typeof(Int32)),
new DataColumn("DocID",typeof(Int32)),
new DataColumn("Days",typeof(Int32)) });
foreach (int DocID in listDocIDs)
{
DataTable DocID_times = new DataTable();
using (SqlConnection conn = new SqlConnection(strCon))
{
conn.Open();
SqlDataAdapter adapter = new SqlDataAdapter("getRecordsByDocID", conn);
adapter.SelectCommand.Parameters.Add("@DocID", SqlDbType.Int).Value = DocID;
adapter.SelectCommand.CommandType = CommandType.StoredProcedure;
adapter.Fill(DocID_times);
conn.Close();
}
int j = 0;
for (int i = 0; i < DocID_times.Rows.Count; i++)
{
j = i + 1;
if (i < (DocID_times.Rows.Count - 1))
{
DateTime tempo1 = DateTime.ParseExact(DocID_times.Rows[i]["Time"].ToString(), "dd-MM-yyyy HH:mm:ss",
System.Globalization.CultureInfo.InvariantCulture);
DateTime tempo2 = DateTime.ParseExact(DocID_times.Rows[j]["Time"].ToString(), "dd-MM-yyyy HH:mm:ss",
System.Globalization.CultureInfo.InvariantCulture);
double mins = (tempo2 - tempo1).TotalMinutes;
TimeSpan result = TimeSpan.FromMinutes(mins);
double days = result.TotalDays;
var rows = times.Select(string.Format("DepartmentID = {0} AND DocID = {1}", DepartmentID, DocID));
if (rows.Length == 0)
{
// Add your Row
times.Rows.Add(DepartmentID, DocID, days);
}
else
{
// Update your Days
rows[0]["days"] = Convert.ToInt32(rows[0]["days"].ToString()) + days;
}
}
}
}
答案 0 :(得分:0)
如果列出所有行,我会计算while循环中记录之间的天数。它可以完全用SQL完成,但它不会像while循环那样好(它可以一次访问两行)。为了能够在SQL中完全执行它,您必须自己加入表,将每个记录与下一个记录连接起来。
IEnumerable<MySummarizedRow> GetSummarizedRows()
{
using (var entries = GetRowsOrderedByDocIdAndRowId().GetEnumerator())
{
if (entries.MoveNext())
{
var previous = entries.Current;
while (entries.MoveNext())
{
var current = entries.Current;
if (current.DocId == previous.DocId)
yield return new MySummarizedRow(previous.DepartmentId, current.DocId, current.Time.Substract(previous.Time).TotalDays + 1);
previous = current;
}
}
}
}
此函数忽略尚未传递给其他部门的文档的行。您可以轻松地更改产生-1天的新行或类似的行。