I have a data table and I need to merge the cells with the same values in the columns IPC and Second Best Issuer and sum the values in the columns Dirty value PC and Par Value LC. All the values are type string.
For example:
I'm a beginner with query and I'm looking for simple way to do this in C# with LINQ.
Thank You
Try following :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace ConsoleApplication11
{
class Program
{
static void Main(string[] args)
{
DataTable dt = new DataTable();
dt.Columns.Add("IPC", typeof(int));
dt.Columns.Add("Dirty", typeof(int));
dt.Columns.Add("Second", typeof(string));
dt.Columns.Add("Par", typeof(int));
dt.Rows.Add(new object[] { 1, 5, "BB", 55 });
dt.Rows.Add(new object[] { 1, 4, "B", 30 });
dt.Rows.Add(new object[] { 2, 15, "AAA", 20 });
dt.Rows.Add(new object[] { 1, 10, "BB", 80 });
dt.Rows.Add(new object[] { 2, 20, "AA", 90 });
dt.Rows.Add(new object[] { 2, 30, "AAA", 50 });
dt.Rows.Add(new object[] { 1, 5, "B", 60 });
dt.Rows.Add(new object[] { 2, 15, "AA", 70 });
var groups = dt.AsEnumerable().GroupBy(x => new {ipc = x.Field<int>("IPC"), second = x.Field<string>("Second")}).ToList();
DataTable dtsum = dt.Clone();
foreach(var group in groups)
{
dtsum.Rows.Add(new object[] {group.Key.ipc, group.Sum(y => y.Field<int>("Dirty")), group.Key.second, group.Sum(y => y.Field<int>("Par"))});
}
}
}
}
Related
I'm trying to sort a DataTable to be able to get the best selling items by order in C#. The DataTable's fields are orderId, productId, size, and amount (amount = how much of it was bought). The current primary key in the table is comprised of orderId, productId, and size. I would like to get the best selling items by sorting the table in a way that would remove orderId, and have productId and size as the new primary key, and amount as the sum of all amount's for orders with this productId and size.
What would be the best way to do this? I'm attaching my current table data for reference. My table data for reference.
If anything is unclear please let me know, this is my first time using Stack Overflow.
Try following :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace ConsoleApplication20
{
class Program
{
static void Main(string[] args)
{
DataTable dt = new DataTable();
dt.Columns.Add("orderid", typeof(int));
dt.Columns.Add("productid", typeof(int));
dt.Columns.Add("size", typeof(int));
dt.Columns.Add("amount", typeof(int));
dt.Rows.Add(new object[] { 1, 1, 38, 12 });
dt.Rows.Add(new object[] { 1, 1, 41, 6 });
dt.Rows.Add(new object[] { 1, 2, 36, 8 });
dt.Rows.Add(new object[] { 1, 2, 38, 5 });
dt.Rows.Add(new object[] { 1, 3, 46, 2 });
dt.Rows.Add(new object[] { 4, 3, 40, 7 });
dt.Rows.Add(new object[] { 8, 3, 40, 7 });
dt.Rows.Add(new object[] { 9, 2, 40, 9 });
dt.Rows.Add(new object[] { 12, 2, 37, 5 });
dt.Rows.Add(new object[] { 13, 2, 37, 4 });
dt.Rows.Add(new object[] { 14, 2, 38, 3 });
dt.Rows.Add(new object[] { 15, 3, 41, 4 });
dt.Rows.Add(new object[] { 16, 2, 36, 7 });
dt.Rows.Add(new object[] { 16, 3, 41, 5 });
dt.Rows.Add(new object[] { 17, 2, 38, 4 });
dt.Rows.Add(new object[] { 18, 3, 40, 3 });
dt.Rows.Add(new object[] { 19, 5, 38, 9 });
dt.Rows.Add(new object[] { 20, 2, 36, 2 });
dt.Rows.Add(new object[] { 21, 1, 40, 3 });
dt.Rows.Add(new object[] { 22, 1, 38, 8 });
dt.Rows.Add(new object[] { 23, 1, 40, 9 });
dt.Rows.Add(new object[] { 24, 2, 37, 1 });
dt.Rows.Add(new object[] { 25, 5, 39, 4 });
dt.Rows.Add(new object[] { 2034, 3, 40, 3 });
dt.Rows.Add(new object[] { 2035, 2, 37, 6 });
dt.Rows.Add(new object[] { 2035, 3, 40, 5 });
dt.Rows.Add(new object[] { 2036, 2, 36, 2 });
dt.Rows.Add(new object[] { 2037, 2, 37, 3 });
dt.Rows.Add(new object[] { 2037, 3, 41, 7 });
dt.Rows.Add(new object[] { 2038, 1, 39, 3 });
dt.Rows.Add(new object[] { 2038, 5, 37, 4 });
var results = dt.AsEnumerable()
.GroupBy(x => new { productid = x.Field<int>("productid"), size = x.Field<int>("size") })
.Select(x => new { productid = x.Key.productid, size = x.Key.size, count = x.Count(), total = x.Sum(y => y.Field<int>("amount")) })
.OrderByDescending(x => x.count)
.ToList();
}
}
}
I have a table as follows
I have a query that runs each day to find anything that's 5 days old or greater and has a status of "In Progress" and set the status to "Declined".
What I need to be able to do is also set the status to "Declined" for anything with a Linked_ID (child) where the ID (Parent) has been changed.
So in the table I already set ID 1 to "Declined" but I also need to set ID's 2,3,4,8 and 10 to "Declined"
Below is what I have so far, any support would be amazing and really helpful
var Process = from a in db.Table1
where a.Status == "In Progress" && a.Date_Created = DateTime.Now.AddDays(-5)
select a;
foreach (Table1 a in Process)
{
a.Status = "Declined";
}
Try following :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Declined declined = new Declined();
declined.Query(DateTime.Now.AddDays(1));
}
}
public class Declined
{
DataTable dt;
public Declined()
{
dt = new DataTable();
dt.Columns.Add("ID", typeof(int));
dt.Columns.Add("Status", typeof(string));
dt.Columns.Add("Date Created", typeof(DateTime));
dt.Columns.Add("Link_ID", typeof(int));
dt.Rows.Add(new object[] { 1, "In Progress", new DateTime(2020, 9, 25) });
dt.Rows.Add(new object[] { 2, "Completed", new DateTime(2020, 9, 28),1 });
dt.Rows.Add(new object[] { 3, "In Progress", new DateTime(2020, 9, 28),1 });
dt.Rows.Add(new object[] { 4, "In Progress", new DateTime(2020, 9, 28),1 });
dt.Rows.Add(new object[] { 5, "In Progress", new DateTime(2020, 9, 28),2 });
dt.Rows.Add(new object[] { 6, "In Progress", new DateTime(2020, 9, 28),3 });
dt.Rows.Add(new object[] { 7, "In Progress", new DateTime(2020, 9, 28) });
dt.Rows.Add(new object[] { 8, "In Progress", new DateTime(2020, 9, 28),1 });
dt.Rows.Add(new object[] { 9, "In Progress", new DateTime(2020, 9, 28) });
dt.Rows.Add(new object[] { 10, "In Progress", new DateTime(2020, 9, 28),1 });
}
public void Query(DateTime date)
{
List<DataRow> rows = dt.AsEnumerable().Where(x => (x.Field<string>("Status") == "In Progress") && (date.Date.Subtract(x.Field<DateTime>("Date Created")).Days > 5)).ToList();
foreach(DataRow row in rows)
{
if (rows.Count > 0) ChangeChildren_Recursive(row, row.Field<DateTime>("Date Created"));
}
}
public void ChangeChildren_Recursive(DataRow row, DateTime date)
{
int id = row.Field<int>("ID");
DateTime rowDate = row.Field<DateTime>("Date Created").Date;
string status = row.Field<string>("Status");
if((status == "In Progress") && (date != rowDate)) row["Status"] = "Declined";
List<DataRow> children = dt.AsEnumerable().Where(x => (x.Field<int?>("Link_ID") == id) && (x.Field<int?>("Link_ID") != null)).ToList();
foreach (DataRow childRow in children)
{
ChangeChildren_Recursive(childRow, date);
}
}
}
}
I have column in DataTable with RowsOrder postion?
In rowsorder postion data is-
Postion in Column:
1
1a
3
4
6
7
8
9
10
11
2a
11a
12
13a
14
5
2
12b
14c
abc
I want to show Postion
1
1a
2
2a
5
3
4
6
7
8
9
10
11
11a
12
12b
13a
14
14a
14c
.....
..
100
100a
101b
.....
1011a
Use IComparable
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Text.RegularExpressions;
namespace ConsoleApplication5
{
class Program
{
static void Main(string[] args)
{
DataTable dt = new DataTable();
dt.Columns.Add("AlphaNumeric", typeof(string));
dt.Rows.Add(new object[] { "1" });
dt.Rows.Add(new object[] { "1a" });
dt.Rows.Add(new object[] { "3" });
dt.Rows.Add(new object[] { "4" });
dt.Rows.Add(new object[] { "6" });
dt.Rows.Add(new object[] { "7" });
dt.Rows.Add(new object[] { "8" });
dt.Rows.Add(new object[] { "9" });
dt.Rows.Add(new object[] { "10" });
dt.Rows.Add(new object[] { "11" });
dt.Rows.Add(new object[] { "2a" });
dt.Rows.Add(new object[] { "11a" });
dt.Rows.Add(new object[] { "12" });
dt.Rows.Add(new object[] { "13a" });
dt.Rows.Add(new object[] { "14" });
dt.Rows.Add(new object[] { "5" });
dt.Rows.Add(new object[] { "2" });
dt.Rows.Add(new object[] { "12b" });
dt.Rows.Add(new object[] { "14c" });
dt.Rows.Add(new object[] { "abc" });
dt.Rows.Add(new object[] { "1011a" });
dt.Rows.Add(new object[] { "101b" });
dt.Rows.Add(new object[] { "100a" });
dt.Rows.Add(new object[] { "100" });
DataTable sorted = dt.AsEnumerable().OrderBy(x => new SortAlphaNumeric(x.Field<string>("AlphaNumeric"))).CopyToDataTable();
}
}
public class SortAlphaNumeric : IComparable<SortAlphaNumeric>
{
public int? number { get;set;}
public string alpha { get;set;}
public SortAlphaNumeric(string alphaNumeric)
{
string pattern = #"(?'number'\d*)(?'alpha'.*)";
Match match = Regex.Match(alphaNumeric, pattern);
string numberStr = match.Groups["number"].Value;
alpha = match.Groups["alpha"].Value;
if (numberStr.Length > 0)
{
number = (int?)int.Parse(numberStr);
}
}
public int CompareTo(SortAlphaNumeric other)
{
if (number == null)
{
if (other.number == null)
{
return alpha.CompareTo(other.alpha);
}
else
{
return 1 ; //other is greater than this
}
}
else
{
if (other.number == null)
{
return -1; //this is greater than other
}
else
{
if (this.number == other.number)
{
return this.alpha.CompareTo(other.alpha);
}
else
{
return ((int)this.number).CompareTo((int)other.number);
}
}
}
}
}
}
I need to compare two datatables which are having same schema and move the differences into another datatable. Below is my code which is not working fine:
DataTable dt1 = new DataTable("TableChanged");
dt1.Columns.Add("StateID",typeof(int));
dt1.Columns.Add("StateInitial");
dt1.Columns.Add("IsActive");
dt1.Rows.Add(new object[] { 10, "GA", 1 });
dt1.Rows.Add(new object[] { 11, "HI", 0 });
dt1.Rows.Add(new object[] { 12, "ID", 1 });
dt1.Rows.Add(new object[] { 13, "IL", 1 });
dt1.Rows.Add(new object[] { 14, "IN", 0 });
dt1.Rows.Add(new object[] { 15, "IA", 1 });
dt1.Rows.Add(new object[] { 23, "MN", 0 });
DataTable dt2 = new DataTable("TableOriginal");
dt2.Columns.Add("StateID", typeof(int));
dt2.Columns.Add("StateInitial");
dt2.Columns.Add("IsActive");
dt2.Rows.Add(new object[] { 10, "GA", 1 });
dt2.Rows.Add(new object[] { 11, "HI", 1 });
dt2.Rows.Add(new object[] { 12, "ID", 1 });
dt2.Rows.Add(new object[] { 13, "IL", 0 });
dt2.Rows.Add(new object[] { 14, "IN", 1 });
dt2.Rows.Add(new object[] { 15, "IA", 1 });
dt2.Rows.Add(new object[] { 23, "MN", 1 });
var matched = from table1 in dt1.AsEnumerable()
join table2 in dt2.AsEnumerable() on table1.Field<int>("StateID") equals table2.Field<int>("StateID")
//where table1.Field<object>("IsActive") == "0"
where table1.Field<string>("StateInitial") == table2.Field<string>("StateInitial") || table1.Field<object>("IsActive") == table2.Field<object>("IsActive")
select table1;
var missing = from table1 in dt1.AsEnumerable()
where !matched.Contains(table1)
select table1;
After comparison, I want result like:
StateID|StateInitial|IsActive
11 "HI" 0
13 "IL" 1
14 "IN" 0
23 "MN" 0
You can use DataRowComparer.Default, which compares every field of a DataRow, for the LINQ methods Intersect and Except. The latter gives you the missing rows, your desired result:
DataRowComparer<DataRow> fieldComparer = DataRowComparer.Default;
IEnumerable<DataRow> matched = dt1.AsEnumerable().Intersect(dt2.AsEnumerable(), fieldComparer);
IEnumerable<DataRow> missing = dt1.AsEnumerable().Except(dt2.AsEnumerable(), fieldComparer);
If you want to add the missing rows into a third table, you could use:
DataTable result = missing.CopyToDataTable();
But i suggest to use a different way because that throws an exception if there were no missing rows:
DataTable result = dt1.Clone(); // empty, same schema
foreach(DataRow row in missing)
result.ImportRow(row);
I'm using MVC 5 where I have the following Model / table called Question;
I want to produce the following result;
My objective is to obtain a list of records reflecting DISTINCT Topics with an average of all the scores for the given Distinct Topic.
var result = from q in db.Questions
where q.Topic.Distinct()
select new Question
{
Category = q.Category,
Topic = q.Topic,
Store1Rating = db.Questions.Where(x => x.Topic == q.Topic).Average(s1 => s1.Store1Rating).ToString(),
Store2Rating = db.Questions.Where(x => x.Topic == q.Topic).Average(s2 => s2.Store2Rating).ToString()
};
I know I'm way off on the LINQ statement but I only have about 6 weeks of doing basic LINQ statements under my belt. This is a whole other layer of complexity over basic LINQ for me. Thanks in advance!
You can do this by using GroupBy
var result = db.Questions.GroupBy(x => new
//grouping data by category and topic, rows which have same category and topic will be in a group
{
x.Category,
x.Topic
}).Select(g => new
//now selecting category and topic for each group and the data we want
{
g.Key.Category,
g.Key.Topic,
//calculate Store1Rating average of all rows which has same category and topic as this group
Store1Rating = db.Questions.Where(x => x.Category == g.Key.Category && x.Topic == g.Key.Topic).Average(x => x.Store1Rating),
//calculate Store2Rating average of all rows which has same category and topic as this group
Store2Rating = db.Questions.Where(x => x.Category == g.Key.Category && x.Topic == g.Key.Topic).Average(x => x.Store2Rating),
});
Try code below. Use following webpage for reference : https://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
DataTable Questions = new DataTable();
Questions.Columns.Add("Id", typeof(int));
Questions.Columns.Add("Category", typeof(string));
Questions.Columns.Add("Topic", typeof(string));
Questions.Columns.Add("Store1Rating", typeof(int));
Questions.Columns.Add("Store2Rating", typeof(int));
Questions.Rows.Add(new object[] { 1,"Food","Pizza", 5, 6 });
Questions.Rows.Add(new object[] { 2, "Food", "Pizza", 4, 5 });
Questions.Rows.Add(new object[] { 3, "Food", "Ice Cream", 4, 5 });
Questions.Rows.Add(new object[] { 4, "Beverage", "Beer", 3, 4 });
Questions.Rows.Add(new object[] { 5, "Beverage", "Soda", 4, 5 });
Questions.Rows.Add(new object[] { 6, "Food", "Pizza", 5, 6 });
Questions.Rows.Add(new object[] { 7, "Food", "Pizza", 4, 5 });
Questions.Rows.Add(new object[] { 8, "Food", "Ice Cream", 3, 4 });
Questions.Rows.Add(new object[] { 9, "Beverage", "Beer", 4, 5 });
Questions.Rows.Add(new object[] { 10, "Beverage", "Soda", 5, 6 });
var summary = Questions.AsEnumerable()
.GroupBy(x => x.Field<string>("Topic"))
.Select(x => new
{
id = x.FirstOrDefault().Field<int>("Id"),
category = x.FirstOrDefault().Field<string>("Category"),
topic = x.Key,
rating1 = x.Select(y => y.Field<int>("Store1Rating")).ToList().Average(),
rating2 = x.Select(y => y.Field<int>("Store2Rating")).ToList().Average()
}).ToList();
}
}
}