簡體   English   中英

從DataTable對象中選擇不同的列組合,並以另一列為條件,並且缺少一些關鍵信息

[英]Selecting distinct column combinations from a DataTable object with another column as a condition, and some key information missing

這與我之前提出的問題非常相關,我收到了一個很好的答案-現在問題變得更加復雜了: 如何從以另一列為條件的DataTable對象中選擇不同的列組合?

我正在使用C#2010。

我有一個正在使用的DataTable對象,該對象具有以下結構(並填充有示例數據):

"name"    "ID"    "hiredate"    "termdate"
Bobby     1        5/1/2011       7/1/2011
Peggy     2        5/1/2011
Lucy      4                       7/3/2012
Jenny     3        5/2/2011
Jenny     3        5/2/2013
Jenny     3        5/2/2011       6/1/2011
Peggy     2        5/1/2011
Lucy      4        6/1/2012

我想過濾此DataTable以僅保留不同的(“ ID”,“ hiredate”)組合。 此問題有兩個主要特征:1-如果存在重復的(“ ID”,“ hiredate”)條目,則應保留信息最多的條目(即現有的“ termdate”)。 2-有些條目沒有“受聘者”,只有“任期”。 在條件1可以被正確處理之前,它們需要與適當的“受聘者”相匹配(至少我認為是這樣)。

數據表是通過csv創建的,並可能添加了用戶輸入,而不是從數據庫查詢中創建,否則我的生活會輕松很多。

因此,執行此操作后的結果表將是:

"name"    "ID"    "hiredate"    "termdate"
Bobby     1        5/1/2011       7/1/2011
Peggy     2        5/1/2011
Jenny     3        5/2/2013
Jenny     3        5/2/2011       6/1/2011
Lucy      4        6/1/2012       7/3/2012

珍妮有兩個條目,因為她出現了兩個不同的“受雇”值,並且其中一個也被復制了-刪除了沒有“任期”的條目。 露西的兩行已合並-他們有互補的失蹤日期。

關於如何在C#中執行此操作的任何建議? 同樣,我正在使用DataTable對象。 我仍然需要保留“ name”和“ termdate”字段-如果沒有,那么我可以獲得一個不同的(“ ID”,“ hiredate”)列表,但確實需要保留它們。

在我最初的問題中,沒有任何條目帶有“ termdate”,但沒有“ hiredate”,這是公認的解決方案,對我來說很好用:

            DataView dv = new DataView(dt);
            dv.Sort = "ID ASC, HireDate DESC, TermDate DESC";

            string lastID = "0";
            List<DateTime> addedHireDatesForUser = new List<DateTime>();

            foreach (DataRowView drv in dv)
            {
                if (drv["ID"].ToString() != lastID)
                {
                    addedHireDatesForUser = new List<DateTime>();
                    addedHireDatesForUser.Add(DateTime.Parse(drv["HireDate"].ToString()));

                    // NEXT ID, ADD ROW TO NEW DATATABLE
                }
                else if (!addedHireDatesForUser.Contains(DateTime.Parse(drv["HireDate"].ToString())))
                {
                    addedHireDatesForUser.Add(DateTime.Parse(drv["HireDate"].ToString());

                    // NEXT DATE, ADD ROW TO NEW DATATABLE
                }

                lastID = drv["ID"].ToString();
            }

我正在尋找的是(至少在某種程度上)優雅的方法的幫助,該方法還可以處理此過程中缺少“已租用”的條目。 我可以編寫一個效率很低的循環來匹配所有這些循環,但是由於(實際上)該表中有成千上萬個條目,所以我想知道是否有更好的方法。

我感謝任何建議!

是否附有SQL查詢? 如果是這樣,查詢就像

SELECT name, ID, hiredate, termdate from table

可以切換到

--First query returns combined record where they have a null in hiredate and one in termdate
SELECT t1.name, t1.ID, max(t2.hiredate) as hiredate, max(t1.termdate) as termdate from table t1
inner join table t2 on t1.id = t2.id and t1.hiredate is null and t2.hiredate is null
GROUP by t1.name, t1.ID
UNION
--Second query returns full records where both hiredate and termdate are there
SELECT name, ID, hiredate, termdate from table t1
where t1.hiredate is not null and termdate is not null
UNION
--Third query returns all records with a different hiredate that have no termdate and include them
SELECT name, ID, hiredate, termdate from table t1
LEFT OUTER JOIN t2 on t1.ID = t2.ID and t1.hiredate = t2.hiredate
where t1.termdate is null and t2.hiredate is null

這應該涵蓋您討論的所有情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM