Comment sélectionner des lignes distinctes dans une table de données et stocker dans un tableau

169

J'ai un ensemble de données objds. objds contient une table nommée Table1. Table1 contient la colonne nommée ProcessName. Ce ProcessName contient des noms répétés, je souhaite donc sélectionner uniquement des noms distincts, est-ce possible.

  intUniqId[i] = (objds.Tables[0].Rows[i]["ProcessName"].ToString());
Ahmed Atia
la source
Publiez un exemple de code, à partir d'un commentaire que vous avez fait ci-dessous, il semble que la réponse dépend des spécificités de la requête avec laquelle vous travaillez.
MatthewMartin

Réponses:

360
DataView view = new DataView(table);
DataTable distinctValues = view.ToTable(true, "Column1", "Column2" ...);
Thomas Levesque
la source
si j'ai 2 colonnes «mo» et «nom», j'ai besoin d'obtenir le «mo» distinct mais pas le «nom» distinct, mais j'ai besoin de garder la colonne «nom» dans ma datatable que dois-je faire?
User7291
1
@JocelyneElKhoury, ça n'a pas vraiment de sens ... quelle valeur de "nom" garderez-vous alors?
Thomas Levesque
@ThomasLevesque peu importe lequel ... disons que je dois garder la première valeur du nom
User7291
17
OK, alors vous avez besoin d'un groupement, pas distinct. Vous pouvez le faire avec Linq to DataSet:table.AsEnumerable().GroupBy(row => row.Field<int>("mo")).Select(group => group.First()).CopyToDataTable()
Thomas Levesque
148

Suivre une seule ligne de code évitera les lignes dupliquées d'un DataTable:

dataTable.DefaultView.ToTable(true, "employeeid");

Où:

  • Le premier paramètre dans ToTable()est un booléen qui indique si vous voulez des lignes distinctes ou non.

  • Le deuxième paramètre dans le ToTable()est le nom de la colonne sur la base duquel nous devons sélectionner des lignes distinctes. Seules ces colonnes seront dans la table de données retournée.

La même chose peut être faite à partir d'un DataSet, en accédant à un DataTable:

dataSet.Tables["Employee"].DefaultView.ToTable(true, "employeeid");
Rahul
la source
5
j'aime le plus cette réponse, car elle pointe vers la DefaultViewpropriété d'un DataTable.
Ian Boyd
Et si j'ai besoin d'être distinct sur la base de deux colonnes?
LCJ
1
@Lijo, la ToTable(boolean, params string[] columnNames)méthode permet de spécifier plusieurs colonnes.
Kristen Hammack
57
DataTable dt = new DataTable();
dt.Columns.Add("IntValue", typeof(int));
dt.Columns.Add("StringValue", typeof(string));
dt.Rows.Add(1, "1");
dt.Rows.Add(1, "1");
dt.Rows.Add(1, "1");
dt.Rows.Add(2, "2");
dt.Rows.Add(2, "2");

var x = (from r in dt.AsEnumerable()
        select r["IntValue"]).Distinct().ToList();
Martin Moser
la source
30

Avec LINQ (.NET 3.5, C # 3)

var distinctNames = ( from row in DataTable.AsEnumerable()
 select row.Field<string>("Name")).Distinct();

 foreach (var name in distinctNames ) { Console.WriteLine(name); }
Zain Ali
la source
15

Vous pouvez utiliser comme ça:

data est DataTable

data.DefaultView.ToTable(true, "Id", "Name", "Role", "DC1", "DC2", "DC3", "DC4", "DC5", "DC6", "DC7");  

mais les performances seront en baisse. essayez d'utiliser le code ci-dessous:

data.AsEnumerable().Distinct(System.Data.DataRowComparer.Default).ToList();  

Pour la performance; http://onerkaya.blogspot.com/2013/01/distinct-dataviewtotable-vs-linq.html

onerkaya
la source
13
var distinctRows = (from DataRow dRow in dtInventory.Rows
                                select dRow["column_name"] ).Distinct();

var distinctRows = (from DataRow dRow in dtInventory.Rows
                                select dRow["col1"], dRow["col2"].. ).Distinct();
ces2601
la source
@Adi Lester: peut-être sélectionner new {col1 = dRow ["col1"], col2 = dRow ["col2"], ...}) .Distinct (); est plus correct?
Urik
Lorsque vous avez juste une liste <DataRow>, vous pouvez faire ceci: var test = (à partir de DataRow dRow dans vm.LiveAssets, sélectionnez dRow ["manname"]). Distinct ();
pat capozzi
La première ligne fonctionne. Le second, comme Urik le souligne, mais celui d'Urik ne fonctionne pas non plus car Distinct () ne trouvera pas d'égalité lors de la comparaison d'objets sur des types anonymes.
Alan Baljeu
9

Pour améliorer la réponse ci-dessus: La fonction ToTable sur dataview a un indicateur "distinct".

//This will filter all records to be distinct
dt = dt.DefaultView.ToTable(true);
Ravedave
la source
1
Cela ne semble pas fonctionner. Il n'y a qu'une seule surcharge avec un paramètre booléen distinct et elle nécessite le tableau de paramètres. Je pense que cela va simplement renvoyer une table appelée "True" sans aucun DISTINCT appliqué.
proudgeekdad
2
+1 Cela fonctionne réellement (au moins dans .NET 4.5). Si vous spécifiez la valeur booléenne "True" comme seul paramètre, il effectue un DISTINCT sur toutes les colonnes de DataView.
SetFreeByTruth
4

Travaux suivants. Je l'ai fonctionné pour moi avec .NET 3.5 SP1

// Create the list of columns
String[] szColumns = new String[data.Columns.Count];
for (int index = 0; index < data.Columns.Count; index++)
{
    szColumns[index] = data.Columns[index].ColumnName;
}

// Get the distinct records
data = data.DefaultView.ToTable(true, szColumns);
Vijay Balani
la source
3

Je viens de trouver ceci: http://support.microsoft.com/default.aspx?scid=kb;en-us;326176#1

Tout en recherchant quelque chose de similaire, uniquement, spécifiquement pour .net 2.0

Je suppose que l'OP recherchait distinct lors de l'utilisation de DataTable.Select (). (Select () ne prend pas en charge distinct)

Voici donc le code du lien ci-dessus:

class DataTableHelper 
{
    public DataTable SelectDistinct(string TableName, DataTable SourceTable, string FieldName)
    {   
        DataTable dt = new DataTable(TableName);
        dt.Columns.Add(FieldName, SourceTable.Columns[FieldName].DataType);

        object LastValue = null; 
        foreach (DataRow dr in SourceTable.Select("", FieldName))
        {
            if (  LastValue == null || !(ColumnEqual(LastValue, dr[FieldName])) ) 
            {
                LastValue = dr[FieldName]; 
                dt.Rows.Add(new object[]{LastValue});
            }
        }

        return dt;
    }

    private bool ColumnEqual(object A, object B)
    {

        // Compares two values to see if they are equal. Also compares DBNULL.Value.
        // Note: If your DataTable contains object fields, then you must extend this
        // function to handle them in a meaningful way if you intend to group on them.

        if ( A == DBNull.Value && B == DBNull.Value ) //  both are DBNull.Value
            return true; 
        if ( A == DBNull.Value || B == DBNull.Value ) //  only one is DBNull.Value
            return false; 
        return ( A.Equals(B) );  // value type standard comparison
    }
}
Gédéon
la source
2
string[] TobeDistinct = {"Name","City","State"};
DataTable dtDistinct = GetDistinctRecords(DTwithDuplicate, TobeDistinct);

//Following function will return Distinct records for Name, City and State column.
public static DataTable GetDistinctRecords(DataTable dt, string[] Columns)
{
    DataTable dtUniqRecords = new DataTable();
    dtUniqRecords = dt.DefaultView.ToTable(true, Columns);
    return dtUniqRecords;
}
Tanmay Nehete
la source
2

Syntaxe:-

DataTable dt = ds.Tables[0].DefaultView.ToTable(true, "ColumnName");

EX:-

DataTable uniqueCols = dsUDFlable.Tables[0].DefaultView.ToTable(true, "BorrowerLabelName");
user3639409
la source
2

La solution la plus simple consiste à utiliser LINQ, puis à transformer le résultat en DataTable

    //data is a DataTable that you want to change
    DataTable result = data.AsEnumerable().Distinct().CopyToDataTable < DataRow > ();

Ceci n'est valable que pour asp.net 4.0 ^ Framework et il a besoin de la référence à System.Data.DataSetExtensions comme l'a souligné Ivan Ferrer Villa

Davide Castronovo
la source
1
il a peut-être besoin de la référence àSystem.Data.DataSetExtensions
Ivan Ferrer Villa
1
var ValuetoReturn = (from Rows in YourDataTable.AsEnumerable()
select Rows["ColumnName"]).Distinct().ToList();
Dylan
la source
1
DataTable dt = new DataTable("EMPLOYEE_LIST");

DataColumn eeCode = dt.Columns.Add("EMPLOYEE_CODE", typeof(String));
DataColumn taxYear = dt.Columns.Add("TAX_YEAR", typeof(String));
DataColumn intData = dt.Columns.Add("INT_DATA", typeof(int));
DataColumn textData = dt.Columns.Add("TEXT_DATA", typeof(String));

dt.PrimaryKey = new DataColumn[] { eeCode, taxYear };

Il filtre la table de données avec le code électronique et l'année fiscale considérés comme uniques

Viswa Teja Kuncham
la source
0

C'est facile

    DataView view = new DataView(dt);
DataTable dt2 = view.ToTable(true, "Column1", "Column2","Column3", ...,"ColumnNth");

et dt2 datatable contiennent des données uniques column1, Column2..ColumnNth.

Manish Singh
la source
0
objds.Table1.Select(r => r.ProcessName).AsEnumerable().Distinct();
Gál Gyula
la source
Salut @ GálGyula, bienvenue dans Stack Overflow! Ici, nous nous soucions des réponses avec de bonnes explications, pas seulement du code. Ne postez une réponse que si elle résout vraiment la question et que vous pouvez expliquer comment. Pour améliorer vos futures réponses, jetez un œil au guide comment rédiger une bonne réponse .
Erick Petrucelli
-1

quelque chose comme?

SELECT DISTINCT .... FROM table WHERE condition

http://www.felixgers.de/teaching/sql/sql_distinct.html

note: question sur les devoirs? et que Dieu bénisse Google.

http://www.google.com/search?hl=fr&rlz=1C1GGLS_enJO330JO333&q=c%23+selecting+distinct+values+from+table&aq=f&oq=&aqi=

Madi D.
la source
3
à quiconque m'a refusé: S ,, évidemment la question a été modifiée après ma réponse ?? (réponse 10:15, question modifiée le 12:15) eh bien .. merci pour votre ignorance :)
Madi D.
2
OP demande comment sélectionner des lignes distinctes dans un environnement C # ado.net, pas dans une base de données réelle.
aggaton
-1
DataTable dtbs = new DataTable(); 
DataView dvbs = new DataView(dt); 
dvbs.RowFilter = "ColumnName='Filtervalue'"; 
dtbs = dvbs.ToTable();
Packiyaraj Shanmugam
la source