我正在使用C#ConoleApplication。
我有ODBC DSN连接,我带入Datatable。 第一列是#34;帐号#"。
示例:
帐号------------ |
AA1 ------------------- |
AA1 ------------------- |
AA2 ------------------- |
AA3 ------------------- |
------------------- AA1 |
AA4 ------------------- |
AA2 ------------------- |
我正在尝试研究如何给出以下结果。 我认为它将被整合到一个新的数据表中,但我不能使任何代码工作,我尝试过。
帐号------------ | OCCURENCES
AA1 ------------------- | 3
AA2 ------------------- | 2
AA3 ------------------- | 1
AA4 ------------------- | 1
请问我该怎么做?
答案 0 :(得分:6)
您可以使用Linq-To-DataTable
和Enumerable.GroupBy
:
var accountGroups = table.AsEnumerable()
.GroupBy(row => row.Field<String>("Account#"))
.Select(grp => new { Account = grp.Key, Count = grp.Count() });
如果您需要新的DataTable
:
var tblAccCounts = new DataTable();
tblAccCounts.Columns.Add("Account#");
tblAccCounts.Columns.Add("Count", typeof(int));
foreach(var grp in accountGroups)
tblAccCounts.Rows.Add(grp.Account, grp.Count);
答案 1 :(得分:1)
对于LINQ,DataTable有点奇怪,但它可以做到。关键是转换DataTable.Rows返回的DataRowCollection。
var results = DataTable.Rows
.Cast<DataRow>()
.GroupBy(row => row.Field<string>(0))
.Select(g => new { Account = g.Key, Occurrences = g.Count()});
将结果导入新的DataTable有点复杂,因为您需要手动创建表。
DataTable newTable = new DataTable();
newTable.Columns.Add(new DataColumn("Account#", typeof(string)));
newTable.Columns.Add(new DataColumn("Occurrences", typeof(int)));
foreach(var result in results)
{
var row = newTable.Rows.NewRow();
row[0] = result.Account;
row[1] = result.Occurrences;
newTable.Rows.Add(row);
}
编辑:蒂姆的解决方案也有效:)
答案 2 :(得分:0)
未经测试,但使用linq会让您的生活更轻松
using System.Linq;
dynamic amounts = dataTable
.AsQueryable()
.GroupBy(item => item.AccountNumber)
.Select(list => new{ AccountNumber: list.Key, Amount: list.Count() }).ToList();
答案 3 :(得分:0)
也许这会奏效。刚在我的数据库上试过它。
按帐户从表格组中选择帐户,计数(帐户);
答案 4 :(得分:0)
你可以试试这个:
class Program
{
static void Main(string[] args)
{
testClass tc = new testClass();
DataTable dt = tc.getTestData();
for(int i = 0; i < dt.Rows.Count; i++)
{
Console.WriteLine("Account No {0} Occurence {1}", dt.Rows[i]["ACCNO"].ToString(), dt.Rows[i]["Occurence"].ToString());
}
}
}
class testClass
{
public string AccountNo { get; set; }
private SqlConnection Conn;
private void TestConnect()
{
string strConn = "Data source = .\\SQLEXPRESS2012; Initial catalog = TEST; Integrated security = SSPI;";
Conn = new SqlConnection(strConn);
}
public DataTable getTestData()
{
TestConnect();
string cmdStr = "SELECT ACCNO, COUNT(XYZ.ACCNO) AS 'Occurence' FROM XYZ GROUP BY ACCNO;";
SqlCommand cmd = new SqlCommand(cmdStr, Conn);
SqlDataAdapter sda = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
try
{
Conn.Open();
sda.Fill(dt);
}
catch (SqlException se)
{
Console.WriteLine("Error occured {0}", se.ToString());
}
finally
{
Conn.Close();
}
return dt;
}
}
答案 5 :(得分:0)
简单可靠的解决方案
我认为这就是你想要的。
示例代码
// Create Results DataTable
DataTable ResultsDataTable = new DataTable();
ResultsDataTable.Columns.Add("Account#"); // Columns default to System.string
ResultsDataTable.Columns.Add("Occurances", Type.GetType("System.Int32"));
ResultsDataTable.AcceptChanges(); //This asserts any changes to your table structure.
// Populate Results DataTable
foreach (DataRow SourceDataRow in SourceDataTable.Rows)
{
string AccountNumber = SourceDataRow["Account#"].ToString();
bool IsPresent = false;
foreach(DataRow ResultsDataRow in ResultsDataTable.Rows)
{
if(ResultsDataRow["Account#"].ToString() == AccountNumber)
{
ResultsDataRow["Occurances"] = ((int)ResultsDataRow["Occurances"]) + 1; //Row exists for this account number, so increment the occurances value
IsPresent = true;
break;
}
}
if (!IsPresent)
{
// There isn't a row for this Account number, so create one and set it to one.
DataRow NewResultsRow = ResultsDataTable.NewRow();
NewResultsRow["Account#"] = AccountNumber;
NewResultsRow["Occurances"] = 1;
ResultsDataTable.Rows.Add(NewResultsRow);
ResultsDataTable.AcceptChanges();
}
}
ResultsDataTable.AcceptChanges();
关于此示例的说明
我不知道你的源DataTable被调用了什么,所以我称之为SourceDataTable。
同样,我创建了一个名为ResultsDataTable的结果数据表。
这大约是最近的Linq等值的两倍
这涵盖了操作DataTables的大多数常用方法,因此它应该能够帮助您在将来自行解决类似的问题。
我希望它有所帮助并祝你好运。
答案 6 :(得分:0)
最佳实践方法当然是采用其他答案所示的 Linq 框架。
但是,如果您想要一种更“零原则”的方法,为您提供列中每个项目的计数,我会提出以下建议。请注意,此方法实际上更灵活一些,因为它返回该列中每个项目 的计数的字典或“地图”,而不仅仅是您要查找的那个。然后您需要做的就是在地图上查询您的特定项目。
private DataTable dt;
...
private Dictionary<string, int> countColumnOccurances(int columnIndex)
{
//Make a unique list of Items for the column of interest
string indexName = dt.Columns[columnIndex].ColumnName;
DataView view = new DataView(dt);
DataTable distinctColumnDT = view.ToTable(true, dt.Columns[columnIndex].ColumnName);
List<String> listOfDistinctItems = new List<String>();
foreach (DataRow r in distinctColumnDT.Rows)
{
listOfDistinctItems.Add(r[indexName].ToString());
}
//Associate each of these items with a count
var itemsAndTheirCount = new Dictionary<String, int>();
int count = 0;
foreach (var l in listOfDistinctItems)
{
foreach (DataRow r in dt.Rows)
{
if (l == r[indexName].ToString())
{
count++;
}
}
itemsAndTheirCount.Add(l, count);
count = 0;
}
return itemsAndTheirCount;
}
包括冗长和冗长,以便您可以遵循逻辑,但是,您可以轻松减少行数。
答案 7 :(得分:-1)
您正在使用SqlServer?如果是这样,你可以在bd上这样做:
SELECT Account#, Count(*) FROM [Table] GROUP BY Account#