วิธีการเลือกแถวที่แตกต่างใน DataTable และเก็บไว้ในอาร์เรย์


169

ฉันมีชุดข้อมูล objds objds มีตารางชื่อ Table1 Table1 มีคอลัมน์ชื่อ ProcessName ProcessName นี้มีชื่อซ้ำกันดังนั้นฉันต้องการเลือกเฉพาะชื่อที่แตกต่างเป็นไปได้นี้

  intUniqId[i] = (objds.Tables[0].Rows[i]["ProcessName"].ToString());

โพสต์โค้ดตัวอย่างจากความคิดเห็นที่คุณทำไว้ด้านล่างดูเหมือนว่าคำตอบจะขึ้นอยู่กับเฉพาะของแบบสอบถามที่คุณใช้
MatthewMartin

คำตอบ:


360
DataView view = new DataView(table);
DataTable distinctValues = view.ToTable(true, "Column1", "Column2" ...);


หากฉันมี 2 คอลัมน์ "mo" และ "name" ฉันต้องได้รับ "mo" ที่แตกต่างกัน แต่ไม่ใช่ชื่อ "ที่ชัดเจน" แต่ฉันต้องเก็บคอลัมน์ "name" ไว้ใน DataTable ของฉันฉันควรทำอย่างไร
User7291

1
@JocelyneElKhoury นั่นมันไม่สมเหตุสมผล ... จริงๆแล้วค่าของชื่อ "ที่คุณจะเก็บเอาไว้?
โทมัสเลวีส

@ThomasLevesque มันไม่สำคัญว่าอันไหน ... สมมุติว่าฉันต้องเก็บค่าแรกของชื่อไว้
User7291

17
ตกลงแล้วคุณต้องจัดกลุ่มไม่แตกต่างกัน คุณสามารถทำได้ด้วย Linq ไปยังชุดข้อมูล:table.AsEnumerable().GroupBy(row => row.Field<int>("mo")).Select(group => group.First()).CopyToDataTable()
Thomas Levesque

148

การติดตามรหัสบรรทัดเดียวจะหลีกเลี่ยงแถวที่ซ้ำกันของDataTable:

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

ที่ไหน:

  • พารามิเตอร์แรกในToTable()เป็นบูลีนซึ่งระบุว่าคุณต้องการแถวที่แตกต่างหรือไม่

  • พารามิเตอร์ที่สองในToTable()คือชื่อคอลัมน์ตามที่เราต้องเลือกแถวที่แตกต่างกัน เฉพาะคอลัมน์เหล่านี้เท่านั้นที่จะอยู่ในประเภทข้อมูลที่ส่งคืน

สิ่งเดียวกันสามารถทำได้จากการDataSetโดยการเข้าถึงเฉพาะDataTable:

dataSet.Tables["Employee"].DefaultView.ToTable(true, "employeeid");

5
ผมชอบคำตอบนี้มากที่สุดเท่าที่จะชี้ไปที่ทรัพย์สินของDefaultView DataTable
เอียนบอยด์

ถ้าฉันต้องแยกความแตกต่างจากสองคอลัมน์ล่ะ
LCJ

1
@Lijo ToTable(boolean, params string[] columnNames)วิธีการอนุญาตให้ระบุหลายคอลัมน์
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();

30

ด้วย 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); }

15

คุณสามารถใช้สิ่งต่อไปนี้:

data คือ DataTable

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

แต่ประสิทธิภาพจะลดลง ลองใช้รหัสด้านล่าง:

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

สำหรับประสิทธิภาพ; http://onerkaya.blogspot.com/2013/01/distinct-dataviewtotable-vs-linq.html


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();

@Adi Lester: อาจเลือกใหม่ {col1 = dRow ["col1"], col2 = dRow ["col2"], ... }) .Distinct (); ถูกต้องมากขึ้น?
Urik

เมื่อคุณมีรายการ <DataRow> คุณสามารถทำได้: var test = (จาก DataRow dRow ใน vm.LiveAssets เลือก dRow ["manname"]) Distinct ();
pat capozzi

บรรทัดแรกใช้งานได้ ข้อที่สองที่ Urik ชี้ให้เห็นไม่เป็นเช่นนั้น แต่ Urik ก็ไม่ทำงานเหมือน Distinct () จะไม่พบความเท่าเทียมกันเมื่อทำการเปรียบเทียบออบเจ็กต์กับชนิดที่ไม่ระบุตัวตน
Alan Baljeu

9

เพื่อปรับปรุงคำตอบข้างต้น: ฟังก์ชั่น ToTable บนดาต้าวิวมีธง "ชัดเจน"

//This will filter all records to be distinct
dt = dt.DefaultView.ToTable(true);

1
ดูเหมือนว่าจะใช้งานไม่ได้ มีเพียงโอเวอร์โหลดเดียวที่มีพารามิเตอร์บูลีนที่แตกต่างในนั้นและต้องใช้อาร์เรย์พารามิเตอร์ ฉันคิดว่าสิ่งนี้จะส่งคืนตารางที่เรียกว่า "จริง" โดยไม่ต้องใช้ DISTINCT ใด ๆ
proudgeekdad

2
+1 สิ่งนี้ใช้งานได้จริง (อย่างน้อยก็ใน. NET 4.5) ถ้าคุณระบุค่าบูลีน "True" เป็นพารามิเตอร์เท่านั้นมันจะทำการ DISTINCT ในคอลัมน์ทั้งหมดใน DataView
SetFreeByTruth

4

ผลงานต่อไปนี้ ฉันทำงานให้ฉันด้วย. 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);

3

ฉันเพิ่งพบสิ่งนี้: http://support.microsoft.com/default.aspx?scid=kb;en-us;326176#1

ในขณะที่กำลังมองหาสิ่งที่คล้ายกันเฉพาะเฉพาะสำหรับ. net 2.0

ฉันสมมติว่า OP กำลังมองหาที่แตกต่างขณะใช้ DataTable.Select () (เลือก () ไม่สนับสนุนชัดเจน)

ดังนั้นนี่คือรหัสจากลิงค์ด้านบน:

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
    }
}

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;
}

2

ไวยากรณ์: -

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

EX: -

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

2

ทางออกที่ง่ายที่สุดคือการใช้ LINQ แล้วแปลงผลลัพธ์ให้เป็น DataTable

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

ใช้ได้กับ asp.net 4.0 ^ Framework เท่านั้นและต้องการการอ้างอิงถึง System.Data.DataSetExtensionsเนื่องจาก Ivan Ferrer Villa ชี้ให้เห็น


1
อาจจำเป็นต้องมีการอ้างอิงถึงSystem.Data.DataSetExtensions
Ivan Ferrer Villa


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 };

มันกรองตารางข้อมูลที่มี eecode และ taxyear รวมกันถือว่าไม่ซ้ำกัน


0

มันง่าย

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

และ dt2 datatable มี column1, Column2..ColumnNth ข้อมูลเฉพาะ


0
objds.Table1.Select(r => r.ProcessName).AsEnumerable().Distinct();

สวัสดี@GálGyulaยินดีต้อนรับสู่ Stack Overflow! ที่นี่เราใส่ใจกับคำตอบด้วยคำอธิบายที่ดีไม่ใช่แค่รหัส โพสต์คำตอบเฉพาะเมื่อแก้ปัญหาได้จริงและคุณสามารถอธิบายได้อย่างไร เพื่อปรับปรุงคำตอบในอนาคตของคุณลองดูคำแนะนำว่าฉันจะเขียนคำตอบที่ดีได้อย่างไร
Erick Petrucelli

-1

ทำให้ตกใจเหมือน

เลือก DISTINCT .... จากตาราง WHERE เงื่อนไข

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

หมายเหตุ: คำถามการบ้าน? และขอให้พระเจ้าคุ้มครอง google ..

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


3
เพื่อใครก็ตามที่ลงคะแนนให้ฉัน: S ,, เห็นได้ชัดว่าคำถามถูกแก้ไขหลังจากคำตอบของฉัน ?? (คำตอบ 10:15 คำถามแก้ไขเมื่อ 12:15) แหมดี .. ขอบคุณสำหรับความไม่รู้ครับ :)
เมดิสัน D.

2
OP ขอวิธีเลือกแถวที่แตกต่างในสภาพแวดล้อม C # ado.net ไม่ใช่ในฐานข้อมูลจริง
aggaton

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.