2013-02-10 73 views
0

我有一個逗號分隔格式的文本文件。每行有兩列,每列有整數值。 Like在1000萬行中查找記錄

12334,23433 
23234,45663 
234422,324545 
324543,23433 
143233,23433 
..... 

重複第二列中的值。我需要做的是在第一列中找到第二列具有相同值並在一行中表示它們的所有值。像上面的數據:

23433 12334,324543,143233 
45663 23234 
324545 234422 

我所做的是以下幾點:

使用逗號
  1. 導入的文本文件導入到SQL Server表(,)作爲分隔符 。
  2. 從每行代碼中讀取文本文件。
  3. 以逗號(,)爲基礎的分割線並使用第二列值向SQL Table發送 查詢。
  4. 將結果存儲在字典數據結構中,其中鍵爲第二列 並將所有結果連接起來形成第一列值。
  5. 畢竟處理完畢後,遍歷字典並將其寫入一個文件中。

這絕對是花費太多時間。我用C#編寫代碼。 T-SQL中的任何解決方案都可以工作。

任何幫助來優化它。

+1

指數可能? – leppie 2013-02-10 17:03:26

+0

如何向我們展示您正在使用的查詢? – vcsjones 2013-02-10 17:03:51

+0

我對此一無所知,但我會假設你可以在很大程度上縮短檢查時間,如果你只是檢查每個數字中的第一個字節,並將其他所有內容放在新表格中,然後釋放原始表格(釋放內存),然後用第二個字節重複該過程,依此類推,直到完成最大數目字節的數目爲止。 – 2013-02-10 17:04:40

回答

1

只使用順序通過以時間來處理一個COL2

select col1, col2 
from table 
order by col2, col1 

然後就寫出來的線,當你得到COL2

Int col2Last = 0; // assume 0 is not a valid value 
StringBuilder sb = new string builder(); 

    while (rdr.read()); 
    { 
     col1 = rdr.GetInt(0); 
     col2 = rdr.GetInt(1); 
     if(col2 != col2Last and col2Last !=0) 
     { 
      Console.WriteLine(col2Last.ToString() + " " + sb.ToString()); 
      sb.clear(); 
     } 
     if (sb.Lenght > 0) sb.Append(","); 
     sb.Append(col1.ToString()); 
     col2Last = col2; 
    } 
    Console.WriteLine(col2Last.ToString() + " " + sb.ToString()); 
+0

非常感謝您的回覆,但我不確定「寫出」部分。任何細節請。 – Malik 2013-02-10 17:23:02

+0

但我會嘗試CodesInChaos的答案並消除SQL。 1000萬應該仍然適合記憶。對象大小有1 GB限制。 – Paparazzi 2013-02-10 17:34:01

+0

不要忘記在col2上創建一個索引,這樣排序很快。 – CodesInChaos 2013-02-10 17:40:57

3

一個新值在純C#這樣做應該是隻要數據量小,快速簡單。無需將您的CSV文件拖入SQL數據庫。

只要文件適合你的RAM,最大的成本應該是IO,而不是處理。擁有1000萬行文件,該文件應該有大約100 MB,並且可能需要一秒處理。

var lines = File.ReadLines(inputFilename); 

var table = lines.Select(line => line.Split(',')); 
var groups = table.GroupBy(columns => columns[1]); 
var output = groups.Select(g => g.Key + " " + string.Join(",", g.Select(columns=>columns[0]))); 

File.WriteAllLines(outputFilename, output); 
+0

非常感謝您的回覆。我有超過1000萬行。上面的代碼需要更少的時間嗎? – Malik 2013-02-10 17:32:29

+0

@Malik只要它適合你的RAM,這段代碼應該很快。如果它不適合RAM,您將得到一個異常,否則您的計算機將開始交換。如果發生異常,請切換到64位。 – CodesInChaos 2013-02-10 17:36:51

+1

在「GroupBy」步驟之前將字符串轉換爲int可能會稍微減少所需的內存。 – CodesInChaos 2013-02-10 17:42:26

0

如果導入數據到表呢,爲什麼不試試這種方法:

declare @t table(c1 int, c2 int) 
insert into @t values 
(12334,23433), 
(23234,45663), 
(234422,324545), 
(324543,23433), 
(143233,23433) 

select c2, replace((select cast(c1 as varchar) as 'data()' from @t where c2=t.c2 for xml path('')),' ',', ') 
from 
@t t 
group by c2 
+0

非常感謝您的回覆,但我有一個16522439行的文本文件。我無法運行插入。我使用SQL導入/導出嚮導創建表。任何SQL查詢? – Malik 2013-02-12 11:36:26

+0

這只是一個例子。在我的select語句中使用您創建的表而不是@t。 – msi77 2013-02-13 06:53:04