Select distinct DataTable rows - c#

I have a DataTable where sometimes values in all columns in two or more rows repeat. I would like to get distinct DataTable. The solutions from here and here don't work for me because I have many columns and depending on some conditions, the number of columns changes.
I was thinking maybe something like this
System.Data.DataTable table = new System.Data.DataTable(); // already fulfilled table
DataView view = new DataView(table);
var tableDistinct = view.ToTable(true, table.Columns);
But I can't pass table.Columns as an argument.

I don't know what's going wrong because you haven't said what's not working. However, you could use LINQ(-TO-DataTable):
table = table.AsEnumerable()
.GroupBy(r => new{ Col1 = r["Col1"], Col2 = r["Col2"], Col3 = r["Col3"] })
.Select(g => g.First())
.CopyToDataTable();
Change the columns in the anonymous type according to your column-list.

The ToTable access a list of string params, the following should convert all your columns to array of string so you don't have to enter them manually
System.Data.DataTable table = new System.Data.DataTable(); // already fulfilled table
DataView view = new DataView(table);
var tableDistinct = view.ToTable(true, table.Columns.Cast<DataColumn>().Select(z=>z.ColumnName).ToArray());

Related

Select all columns after filtering Distinct rows based on few columns from a Datatable in c#

I gone through similar questions posted here but didn't find the solution of my problem.
I have a datatable in C# which contains duplicate rows like below:
Now, I have to apply a filter which finds all distinct rows based on Last 2 highlighted columns but in final result set I have to return all columns.
Also, I'll get an ADDRESS_ID whose corresponding row should be
returned and duplicates should be removed.
DataView view = new DataView(ds.Tables[0]);
DataTable distinctValues = view.ToTable(true, "ADDR_LINE_1", "ADDR_LINE_2", "ADDR_LINE_3", "CITY", "STATE", "ZIP", "BOX_NUMBER");
This code is returning 2 rows but not all columns.
Also used this code:
DataTable dtUniqRecords = new DataTable();
dtUniqRecords = ds.Tables[0].DefaultView.ToTable(true, "RELATE_CODE", "ADDRESS_TYPE", "ADDRESS_CODE", "ADDRESS_ID", "ADDR_LINE_1", "ADDR_LINE_2", "ADDR_LINE_3", "CITY", "STATE", "ZIP", "BOX_NUMBER");
But this is returning all rows with duplicates.
You can use GroupBy to filter out duplicate values:
var dt = ds.Tables[0];
var distinct = dt.AsEnumerable()
.GroupBy(g => new
{
Address1 = g.Field<string>("ADDR_LINE_1"),
Address2 = g.Field<string>("ADDR_LINE_2")
// any other fields you need to group by
})
.Select(g => g.First()) // select first group including all columns
.CopyToDataTable();

How To select Specific Column From DataTable in C#?

I have a dataTable with 4 columns ,
I want to select one column without foreach or any other expensive loop and my result must be a new data table with one column ,How can I do this;
DataTable leaveTypesPerPersonnel = LeaveGroup.GetLeaveTypesPerPersonnels(dtPersonnel.row);
leaveTypesPerPersonnel has this columns :
[ID,Guid,LeaveTypeID,Code]
I want Filter leaveTypesPerPersonnel wihtout foreach and get new datatable with just Column [ID]
NOTE: Output must be a Datatable With one column.
leaveTypesPerPersonnel.Columns.Remove("Guid");
leaveTypesPerPersonnel.Columns.Remove("LeaveTypeID");
leaveTypesPerPersonnel.Columns.Remove("Code");
or
DataTable dt= new DataView(leaveTypesPerPersonnel).ToTable(false,"ID");
You should be able to run a quick LINQ statement against the data table.
var results = (from item in leaveTypesPerPersonnel
select item.ID);
This will give you an IEnumerable if I remember correctly. It's not a DataTable, but might provide a solution to your problem as well.
Here is a try on how to search and convert the result to DataTable
var dataTable = leaveTypesPerPersonnel.Rows.Cast<DataRow>().ToList().Where(x=> x["ID"] == 21).CopyToDataTable().DefaultView.ToTable(false, "ID");
Or
var dataTable = leaveTypesPerPersonnel.Select("ID = 21").CopyToDataTable().DefaultView.ToTable(false, "ID");
Or
var dataTable = leaveTypesPerPersonnel.Rows.Cast<DataRow>().ToList().CopyToDataTable().DefaultView.ToTable(false, "ID");

How to load a specific value from a database to dropdownlist?

I have a query which returns a data. Actually it has to return only one row of data, but i have to take several records from different tables and they contain several values for one primary attribute. There according to the query I get several rows. Now I want to load one of the records(one cell of a column) to a dropdownlist. How can I do it?
This is my query
select emp.[App_no]
,emp.[EMP_CALLING_NAME]
,emp.[EMP_INI]
,emp.[EMP_SURNAME]
,emp.[EMP_TITLE]
,emp.[EMP_NAMES_INI]
,emp.[EMP_FULLNAME]
,emp.[EMP_NIC]
,emp.[EMP_dob]
,emp.[EMP_GENDER]
,emp.[NAT_CODE]
,emp.[EMP_MARITAL_STATUS]
,emp.[EMP_DATE_JOINED]
,emp.[EMP_CONFIRM]
,emp.[CX_CODE]
,emp.[DSMG_CODE]
,emp.[CAQT_CODE]
,emp.[EMP_PER_ADDRESS1]
,emp.[EMP_PER_ADDRESS2]
,emp.[EMP_PER_ADDRESS3]
,emp.[EMP_PER_CITY]
,emp.[EMP_PER_TELEPHONE]
,emp.[EMP_PER_MOBILE]
,emp.[EMP_PER_PROVINCE]
,emp.[EMP_PER_DISTRICT]
,emp.[EMP_TEM_ADDRESS1]
,emp.[EMP_TEM_ADDRESS2]
,emp.[EMP_PER_ELECTORATE]
,emp.[EMP_TEM_ADDRESS3]
,emp.[EMP_TEM_CITY]
,emp.[EMP_PER_GD]
,bank.[BBRANCH_CODE]
,bank.[EBANK_ACC_NO]
,bank.[EBANK_ACC_TYPE_FLG]
,bank.[EBANK_ACTIVE_FLAG]
,bank.[LAST_MODIFIED_DATE]
,qual.[Qulif_code]
,lang.[lang_code]
,lang.[ability_type]
,ex.[From_date]
,ex.[To_date]
,ex.[Organization]
,ex.[designation]
,ex.[Cobtact_No]
,nation.[NAT_NAME]
from [EMPLOYEE] emp, [EMP_BANK] bank,
[QUALIF] qual, [LANG] lang,
[Experience] ex, [NATIONALITY] nation
where emp.App_no = bank.App_no and emp.App_no = qual.App_No
and emp.App_no = lang.App_no and nation.NAT_CODE = emp.[NAT_CODE]
and emp.App_no = ex.App_no and emp.App_no=#num
This is how I bind data
ddlDesignations.DataSource = ds.Tables[0];
ddlDesignations.DataTextField = "designation";
ddlDesignations.DataValueField = "designation";
ddlDesignations.DataBind();
This is how the dropdownlist appears
This might do the trick
DataView view = new DataView(ds.Tables[0]);
DataTable distinctValues = view.ToTable(true, "designation");
ddlDesignations.DataSource = distinctValues;
ddlDesignations.DataTextField = "designation";
ddlDesignations.DataValueField = "designation";
ddlDesignations.DataBind();
Here, first parameter in ToTable() is a boolean which indicates whether you want distinct rows or not. and the second parameter in the ToTable() is the column name based on which we have to select distinct rows. Only these columns will be in the returned datatable.
You can use LINQ for this
var distinctdesignations = ds.Tables[0].AsEnumerable()
.Select(row => new {
designation = row.Field<string>("designation")
})
.Distinct();
ddlFamilyMembers.DataTextField = "designation";
ddlFamilyMembers.DataValueField = "designation;
ddlFamilyMembers.DataSource = distinctdesignations;
ddlFamilyMembers.DataBind();

How to select Values from Datatable which appears once

myDataTable has a column named ORDER_NO. I would like to select the rows from this table which appears once. If a value appears two times than it should not selected.
ORDER_NO contain Values
1000A
1001A
1001B
1002A
1002B
1002C
1000A
1001A
1001B
I want to select only form the values above are:
1002A
1002B
1002C
as they appears once in the column. Can anyone help?
So you want only unique rows according to the ORDER_NO column?
Presuming that it's a string column you could use LINQ's Enumerable.GroupBy:
var uniqueRows = table.AsEnumerable()
.GroupBy(row => row.Field<string>("ORDER_NO"))
.Where(group => group.Count() == 1)
.Select(group => group.First());
if you want a new DataTable from the unique rows you can use:
table = uniqueRows.CopyToDataTable();
If you instead only want this column's values:
IEnumerable<string> unqiueOrderNumbers = uniqueRows.Select(row => row.Field<string>("ORDER_NO"));
Apart from #Tim's answer you can also use DataView to simplify this thing
DataView view = new DataView(table);
DataTable distinctValues = view.ToTable(true, "ORDER_NO");
I think this is the simplest way to get distinct values from any table. You can even mention multiple columns in the ToTable method. Just pass column name as argument like ORDER_NO is send in above sample code.

Distinct records in DataTable

I want to get distinct records based on some fields. I'm using the following method:
string[] TobeDistinct = { "PKID" };
DataTable dtDistinct = GetDistinctRecords(ds.Tables[0], TobeDistinct);
DataSet ds2 = new System.Data.DataSet();
ds2.Tables.Add(dtDistinct);
public static DataTable GetDistinctRecords(DataTable dt, string[] Columns)
{
DataTable dtUniqRecords = new DataTable();
dtUniqRecords = dt.DefaultView.ToTable(true, Columns);
return dtUniqRecords;
}
This gives me the distinct records, but only two records come. Only two distinct PKID will come. For example, I have multiple records with PKID 10,12,14,16, but the result is 2 rows with PKID 10 and 12. More two rows are not there, but should be there. What do I need to do?
I follow this article: http://www.codeproject.com/Tips/153008/Select-DISTINCT-records-based-on-specified-fields
You can use like follows
DataView view = new DataView(table);
DataTable distinctValues = view.ToTable(true, "Column1", "Column2" ...);
More detail
How to select distinct rows in a datatable and store into an array
Can you try this?
var myResult = dt.AsEnumerable().Select(c => (DataRow)c["MyColumn"]).Distinct().ToList();

Categories