How to pivot DataTable by Column - c#

I like to group a datatable by a known column but the rest of the columns are unknown. The first table in the picture is the source and the second table is the one i like to produce. Only the column that is needed to group by is sure to be there. I don't know the rest of the columns so it must be dynamic.
So far, i have tried using Linq but it doesn't product the output i wanted.
var dt = res.AsEnumerable()
.GroupBy(r => r.Field<string>("GroupBy"))
.SelectMany(t => t.ToList())
.CopyToDataTable();

When you talk about pivoting a table, you are usually summarizing the data in some fashion -- counting, totaling, averaging. If you only know one column, you can't really pivot it other than to count how many rows are in each group:
var dt = res
.AsEnumerable()
.GroupBy(r => r.Field<String>("ColumnToGroup"))
.Select(r => new { Key = r.Key, Count = r.Count() });
Gives you a pivot table that looks something like:
Key Count
London 2
Manchester 2
To do a useful pivot, you have to know something about the data in the table.

Related

C# Linq How to select the distinct row count of multiple columns in a datatable

I have a datatable with multiple key columns (key1, key2, ..., keyN). I want to count the distinct key combinations in the table, that match a certain criteria (IsInError = false).
Basically i want to perform the query
SELECT COUNT(*) FROM (SELECT DISTINCT key1, key2, ..., keyN FROM TABLE WHERE IsInError = 'false') A
on the datatable.
I have researched a little and found that for a table containing only one key (and with no 'where') I can do this
DataTable table = new DataTable();
int nRows = table
.AsEnumerable()
.Select(r => r.Field<string>("key1"))
.Distinct()
.Count();
But how would I go about doing it with multiple keys and a condition?
Try something like this:
table.AsEnumerable().Where(v => v.Field<bool>("IsInError") == false).Select(_ => new { key1 = _.key1, key2 = _.key2, ...., keyn=_.keyn }).Distinct().Count();
A group by might be more suited to this scenario.
It will group the columns into distinct rows and return a count if desired.
i.e.
var groups = table.GroupBy(_ => new {_.Key1, _.Key2, _.KeyN})
.Select(_ => new { key = _.Key, count = _.Count());
This is untested code, but should help point you in the correct direction.

Select all records of a datatable with duplicate values

How do we select all the record of particular year (e.g. 2014) from a datatable where one of the column value(here 2014) is repeated on multiple rows of
table using linq or any other method in C#.
This is the datatable:
It's been a while since I've worked with DataTables but I think this should do it.
To select rows where the year is duplicated across more than one row:
dt.AsEnumerable().GroupBy(x => x["Year"]).Where(x => x.Count() > 1);
To select only the rows for a particular year:
dt.AsEnumerable().Where(x => x["Year"] == "2014");
Where dt is your System.Data.DataTable.
If you are trying to retrieve all the records lies on the Year 2014, use following linq query,IT will check your data column has data or not, I am sure it will works..
//selecting all the records of 2014
IEnumerable<DataRow> dtrow = default(IEnumerable<DataRow>);
dtrow = yourtable.AsEnumerable().Where(x => x.Field<Int64>("year") == Convert.ToInt64("2014"));
if (dtrow.Count() > 0)
{
dataTbl = dtrow.CopyToDataTable(); //dataTbl is the DataTable
}
Try to do it in database since it is faster than C#. DB can have index but C# does not have.
select *, count(1) as totalCount
group by year
having totalCount > 1

Select row with max value after group in Linq Nhibernate

I have a table:
Table { Id, Date, Number, Bool }
I need to group it by Number, select the row with max Date inside each group, and retrieve Id for each group. In the end I need to filter that to only have records that are !Bool. I am trying to do this with Linq Nhibernate.
This SQL seems to be doing what I want:
select Id from
(select MAX(Date) as Dt, Number as N from Table group by Number) t, Table table
where table.Date = t.Dt and table.Number = t.N and table.Bool = 0
but turns out NHibernate does not allow for subqueries to be in from. How do I write this with Linq Nhibernate?
It's also quite important for it to be efficient, so I would rather avoid having subqueries in select or where if they iterate over the whole set and (N+1) query problem.
The straightforward approach doesn't work either:
Session.Query<Table>().GroupBy(x => x.Number)
.Select(x => x.Where(y => y.Date == x.Max(z => z.Date)))...

Trying to get a list distinct values count per column in the same result column

So for this example lets say I have a DataTable which is called dt and it has some number of columns, I want to get back a list of the column names and how many different values are in each column. Also I would like the result set ordered by the largest to the smallest
For example I have a table with 4 columns and 40 rows of data, in the first column there is 4 distinct values, second column 12, third column 20, fourth column 40. I want my result set to look like this
Column4 40
Column3 20
Column2 12
Column1 4
How could I achieve this using C# and Linq?
Your LINQ code
var result = dt.Columns
.Cast<DataColumn>()
.Select(dc => new {
Name = dc.ColumnName,
Values = dt.Rows
.Cast<DataRow>()
.Select(row => row[dc])
.Distinct()
.Count()})
.OrderBy(item => item.Values);
var result =
dt.Columns
.Cast<DataColumn>()
.Select(c =>
new
{
c.ColumnName,
DistinctValuesCount =
dt.Rows
.Cast<DataRow>()
.Select(r => r[c])
.Distinct()
.Count()
})
.OrderByDescending(i => i.DistinctValuesCount)
.ToArray();

linq select distinct date from a DataTable

I want to fetch distinct date from a DataTable. Currently I'm using the below code:
MyDataTable.DefaultView.ToTable(true, "MyDateColumn");
This code considers the time too but I don't want the time to be considered. I wrote the below code to select only Date Part but while making the distinct it considers the time too.
MyDataTable.AsEnumerable()
.Select(row => new { MyDateColumn = row.Field<DateTime>("MyDateColumn").ToString("d") }).Distinct();
Please help me to select only distinct date(i.e by ignoring time).
You can try Selecting the column by just the Date property of the column:
MyDataTable.AsEnumerable()
.Select(row => row.Field<DateTime>("MyDateColumn").Date).Distinct();

Categories

Resources