특정 조건으로 두 가지 중 하나의 데이터 테이블을 작성하십시오.


13

먼저 ODBC에서 모든 데이터를 가져와야합니다 (이미 작동 중입니다).

그런 다음 아직 어떻게 할 수 있는지 잘 모르는 가장 복잡한 부분이 있습니다. ODBC에는 두 개의 데이터 테이블이 있습니다. 현재 코드와 병합하고 특정 매개 변수로 필터링합니다.

데이터베이스의 표 1 :

NRO   NAME   NAMEA   NAMEB   ADDRESS   POSTA   POSTN   POSTADR   COMPANYN   COUNTRY   ID  ACTIVE
123   Fiat   Punto   500     J5        K4      O3      P4        O2         JT        1   1
133   Opel   Meriva  FTG     J5        K4      O3      P4        O2         JO        3   1
153   MB     E200    C25     JN        KI      OP      PY        OR         JD        5   1
183   BMW    E64     SE0     JR        KE      OT      PG        OL         J8        9   1
103   Audi   S6      700     JP        KU      OU      PN        OH         J6        11  1 

데이터베이스의 표 2 :

NRO   NAME   NAMEA   NAMEB   ADDRESS   POSTA   POSTN   POSTADR   COMPANYN   COUNTRY   ID  ACTIVE
423   Fiat   Punto   500     J5        K4      O3      P4        O2         JT        1   1
463   BMW    E64     SE0     JR        KE      OT      PG        OL         J8        9   1

병합 된 dataTable은 다음과 같습니다.

NRO   NAME   NAMEA   NAMEB   ADDRESS   POSTA   POSTN   POSTADR   COMPANYN   COUNTRY   ID  ACTIVE
423   Fiat   Punto   500     J5        K4      O3      P4        O2         JT        1   1
463   BMW    E64     SE0     JR        KE      OT      PG        OL         J8        9   1
123   Fiat   Punto   500     J5        K4      O3      P4        O2         JT        1   1
133   Opel   Meriva  FTG     J5        K4      O3      P4        O2         JO        3   1
153   MB     E200    C25     JN        KI      OP      PY        OR         JD        5   1
183   BMW    E64     SE0     JR        KE      OT      PG        OL         J8        9   1
103   Audi   S6      700     JP        KU      OU      PN        OH         J6        11  1 

그러나 병합 된 출력 데이터 테이블은 다음과 같이 보일 것입니다 (추가 작업이 가능하도록).

NRO  NRO1   NAME   NAMEA   NAMEB   ADDRESS   POSTA   POSTN   POSTADR   COMPANYN   COUNTRY   ID  ACTIVE
123  423    Fiat   Punto   500     J5        K4      O3      P4        O2         JT        1   1
133         Opel   Meriva  FTG     J5        K4      O3      P4        O2         JO        3   1
153         MB     E200    C25     JN        KI      OP      PY        OR         JD        5   1
183  463    BMW    E64     SE0     JR        KE      OT      PG        OL         J8        9   1
103         Audi   S6      700     JP        KU      OU      PN        OH         J6        11  1 

에서 중복 항목을 찾으십시오 NAME. 그중 하나만 남겨두고 표 1 NRO부터 표 2까지 의 숫자를 할당하십시오 NRO1. 표 1 숫자는 안에 있어야 NRO하고 표 2 숫자는 안에 있어야합니다 NRO1.

ODBC에 연결 한 후 표 1의 데이터로 하나의 테이블을 채우고 있습니다.

        DataTable dataTable = new DataTable("COMPANY");

        using (OdbcConnection dbConnectionSE = new OdbcConnection(connectionStringSE))
        {
            dbConnectionSE.Open();
            OdbcDataAdapter dadapterSE = new OdbcDataAdapter();
            dadapterSE.SelectCommand = new OdbcCommand(queryStringSE, dbConnectionSE);

            dadapterSE.Fill(dataTable);

        }

그런 다음 다른 표 2에서 데이터를 가져 와서 병합합니다.

         using (OdbcConnection dbConnectionFI = new OdbcConnection(connectionStringFI))
         {
              dbConnectionFI.Open();
              OdbcDataAdapter dadapterFI = new OdbcDataAdapter();
              dadapterFI.SelectCommand = new OdbcCommand(queryStringFI, dbConnectionFI);

              var newTable = new DataTable("COMPANY");
              dadapterFI.Fill(newTable);

              dataTable.Merge(newTable);
          }

그 후 필터링을 수행하고 있습니다 (에서 4와 1로 시작하는 행만 있으면 NRO되고 다른 시작 번호가있는 행도 있습니다).

DataTable results = dataTable.Select("ACTIVE = '1' AND (NRO Like '1%' OR NRO Like '4%')").CopyToDataTable();

그런 다음 열을 하나 더 추가합니다 NRO1( 열에 필요하지 않은 0도 추가합니다 NRO1).

        results.Columns.Add("NRO1", typeof(int)).SetOrdinal(1);

        foreach (DataRow row in results.Rows)
        {
            //need to set value to NewColumn column
            row["NRO1"] = 0;   // or set it to some other value
        }

이 코드로 중복을 잡을 수 있습니다

var duplicates = results.AsEnumerable().GroupBy(r => r[2]).Where(gr => gr.Count() > 1);

그러나 나머지는 어떻게 수행합니까? 이것은 새로운 테이블을 만드는 루프에 의해 수행되어야합니까? 어떻게 가입하고에 중복 제거 수행 할 수 있습니다 dataTable?


1.dataTable 일부 이름에 대해 중복을 두 개 이상 포함 할 수 있습니까 ? 예를 들어, BMW에 대해 3 개의 복제본이 존재할 수 있습니까? 2. 보존 할 중복 레코드와 삭제할 레코드를 어떻게 정의 할 수 있습니까? 예를 들어 레코드를 최소로 유지 NRO하고 다른 레코드를 삭제할 수 있습니다 .
Iliar Turdushev

@IliarTurdushev 1. datatable은에 두 개 이상의 "중복"을 포함 할 수 없습니다 NAME. 둘 이상인 경우-오류 (오류 처리기) 2. 내 예제에서 오류가 발생하여 지금 수정했습니다. 이것을 언급 해 주셔서 감사합니다. 중요합니다.
hatman

queryStringFI 및 / 또는 queryStringSE의 값을 공유 할 수 있습니까? 또한 어떤 DB를 사용하고 있습니까?
ATTA

@ATTA 실제 데이터베이스에 대한 액세스를 제공 할 수 없습니다. DB 타입을 의미합니까? 문제는 다음과
같습니다-ODBC

실제로 나는 데이터를 가져 오는 쿼리를보고 싶지만 대답을 쓴 몇 가지 가정을 기반으로합니다. 검토하고 의견을 보내주십시오. 감사합니다
ATTA

답변:


3

merge()호출을 병합 및 필터링을 동시에 수행하는 사용자 정의 메소드로 바꿀 수 있습니다. 아래 예를 참조하십시오. 먼저 병합 (결과 테이블에 중복 행 소개) 후 필터링 (예 : 중복 행 제거)보다 더 나은 방법이라고 생각합니다.

여기서는 매개 변수의 형식이 모두 같다고 가정합니다. tTemp테이블은 테이블의 내용에 대한 임시 저장소로 사용 t2하지만 여분의 열이. 결과 테이블에서 행을 가져올 수 있습니다.

더 우아한 솔루션이있을 수 있지만 의도 한대로 작동해야합니다. 에 허용 된 값에 대한 추가 요구 사항을 생략했으며 NRO쉽게 추가 할 수 있습니다.

static void merge_it(DataTable t1, DataTable t2, DataTable tResult, DataTable tTemp)
    {
        tResult.Merge(t1);
        tResult.Columns.Add("NRO1", typeof(int));

        tTemp.Merge(t2);
        tTemp.Columns.Add("NRO1", typeof(int));

        foreach (DataRow row in tTemp.Rows)
        {
            string name1 = row.Field<string>("NAME");
            string name2 = row.Field<string>("NAMEA");
            DataRow[] matches = tResult.Select($"NAME = '{name1}' AND NAMEA = '{name2}'");
            if (matches.Length > 0)
            {
                matches[0].SetField<int>("NRO1", row.Field<int>("NRO"));
            }
            else
            {
                tResult.ImportRow(row);
            }
        }

        foreach (DataRow row in tResult.Rows)
        {
            if (row["NRO1"] == DBNull.Value)
            {
                row["NRO1"] = 0;
            }
        }
    }

감사합니다! 'DataTable' does not contain a definition for 'Merge_it' and no accessible extension method 'Merge_it' accepting a first argument of type 'DataTable' could be found (are you missing a using directive or an assembly reference?)dataTable.Merge(newTable);dataTable.Merge_it(newTable);
hatman

코드를 새 클래스에 넣을 수 있습니다. 그냥 넣어 class Merger {...}내 코드와 전화 주위에 Merger.merge_it(...). 그래도 입력 매개 변수를 준비해야합니다.
lzydrmr

... using물론 누락 된 지시문 을 추가해야합니다 . (작업 프로그램의) 스 니펫 일뿐입니다.
lzydrmr

tResult.Select에 대한 foreach의 성능에 대해 잘 모르겠습니다. 더 큰 데이터 테이블의 경우 매우 느려질 수 있습니다 (tResult.Select가 O (n)라고 가정하면 foreach를 사용하면 O (n ^ 2) 실행 시간)
CitrusO2

2

이 시도:

  1. Table1 및 Table2에 대한 쿼리 모두에 NRO1 필드 포함
  2. Table1에 대해 NRO1의 기본값 0을 설정하십시오 (queryStringSE 수정).

    예 : SELECT NRO, 0 AS NRO1, NAME, NAMEA, NAMEB, ... FROM TABLE1

  3. Table2에 대해 NRO의 기본값 0을 설정하십시오 (queryStringFI 수정).

    예 : SELECT 0 AS NRO, NRO AS NRO1, NAME, NAMEA, NAMEB, ...... FROM2에서

Table1은 다음과 같습니다.

NRO  NRO1   NAME   NAMEA   NAMEB   ADDRESS   POSTA   POSTN   POSTADR   COMPANYN   COUNTRY   ID  ACTIVE
123   0     Fiat   Punto   500     J5        K4      O3      P4        O2         JT        1   1
133   0     Opel   Meriva  FTG     J5        K4      O3      P4        O2         JO        3   1

Table2는 다음과 같습니다.

NRO  NRO1   NAME   NAMEA   NAMEB   ADDRESS   POSTA   POSTN   POSTADR   COMPANYN   COUNTRY   ID  ACTIVE
0    423    Fiat   Punto   500     J5        K4      O3      P4        O2         JT        1   1
0    463    BMW    E64     SE0     JR        KE      OT      PG        OL         J8        9   1
  1. 이미하고있는 것처럼 테이블 병합

다음 코드 줄을 추가하십시오.

var carGroups = dataTable.AsEnumerable().GroupBy(row => new 
{
   Name = row.Field<string>("Name"),
   NameA = row.Field<string>("NAMEA"),
   NameB = row.Field<string>("NAMEB")
   //Other fields.....
});

DataTable result = dataTable.Clone();

foreach(var grp in carGroups)            
    result.Rows.Add(grp.Sum(r1 => r1.Field<int>("NRO")), grp.Sum(r2 => r2.Field<int>("NRO1")), grp.Key.Name, grp.Key.NameA, grp.Key.NameB);              
  1. 원하는 값에 대한 DataTable "결과"확인

0

동일한 유형의 엔티티를 나타내는 경우 두 테이블에서 동일한 열 이름을 유지할 수 있습니다.이 코드를 참조하십시오.

 private static void DemonstrateMergeTable()
{
    DataTable table1 = new DataTable("Items");

    // Add columns
    DataColumn idColumn = new DataColumn("id", typeof(System.Int32));
    DataColumn itemColumn = new DataColumn("item", typeof(System.Int32));
    table1.Columns.Add(idColumn);
    table1.Columns.Add(itemColumn);

    // Set the primary key column.
    table1.PrimaryKey = new DataColumn[] { idColumn };

    // Add RowChanged event handler for the table.
    table1.RowChanged += new 
        System.Data.DataRowChangeEventHandler(Row_Changed);

    // Add ten rows.
    DataRow row;
    for (int i = 0; i <= 9; i++)
    {
        row = table1.NewRow();
        row["id"] = i;
        row["item"] = i;
        table1.Rows.Add(row);
    }

    // Accept changes.
    table1.AcceptChanges();
    PrintValues(table1, "Original values");

    // Create a second DataTable identical to the first.
    DataTable table2 = table1.Clone();

    // Add column to the second column, so that the 
    // schemas no longer match.
    table2.Columns.Add("newColumn", typeof(System.String));

    // Add three rows. Note that the id column can't be the 
    // same as existing rows in the original table.
    row = table2.NewRow();
    row["id"] = 14;
    row["item"] = 774;
    row["newColumn"] = "new column 1";
    table2.Rows.Add(row);

    row = table2.NewRow();
    row["id"] = 12;
    row["item"] = 555;
    row["newColumn"] = "new column 2";
    table2.Rows.Add(row);

    row = table2.NewRow();
    row["id"] = 13;
    row["item"] = 665;
    row["newColumn"] = "new column 3";
    table2.Rows.Add(row);

    // Merge table2 into the table1.
    Console.WriteLine("Merging");
    table1.Merge(table2, false, MissingSchemaAction.Add);
    PrintValues(table1, "Merged With table1, schema added");
}

private static void Row_Changed(object sender, 
    DataRowChangeEventArgs e)
{
    Console.WriteLine("Row changed {0}\t{1}", e.Action, 
        e.Row.ItemArray[0]);
}

private static void PrintValues(DataTable table, string label)
{
    // Display the values in the supplied DataTable:
    Console.WriteLine(label);
    foreach (DataRow row in table.Rows)
    {
        foreach (DataColumn col in table.Columns)
        {
            Console.Write("\t " + row[col].ToString());
        }
        Console.WriteLine();
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.