Filtrowanie danych

0

Witam,

mam dwa pliki csv, w jednym jest 10000 rekordów, a w drugim 3 miliony. Potrzebuję przefiltrować to 3 miliony i zostawić tylko te rekordy których wartość w "polu1" istnieje w pliku pierwszym w "polu1"
Przykład:
a)plik pierwszy
123,cos,cos
124,cos,cos
32,cos,cos
b)plik drugi
433,cos,cos
432,cos,cos
123,cos,cos
32,cos,cos
543,cos,cos

po filtracji w drugim ma zostać:
123,cos,cos
32,cos,cos

Czego do tego użyć (php,c,java czy np access będzie potrafił to zrobić) żeby udało sie to przefiltrować (plik ma 100mb) ?

0

Najszybciej to chyba php. Wczytujesz pierwszy plik w tablice haszowana, przelatujesz drugi i sprawdzasz czy juz sa w tablicy takie.

$file = fopen("plik1.csv", "r");
$array = array();
while(($row = fgetcsv($file)) !== false)
  array[] = $row[0]; //tylko pierwsze pole nam do szczescia potrzebne
$file2 = fopen("plik2.csv", "r");
$file3 = fopen("output.csv", "w");
while(($row = fgetcsv($file)) !== false)
  if(array[$row[0]] !== null)
    fputcsv($file3, $row);
fclose($file);
fclose($file2);
fclose($file3);

W sql wystarczy wczytac dwa pliki w osobne tabele i zadac zapytanie:

select t2.* from tabela2 t2 inner join tabela1 t1 on t1.pole1 = t2.pole1

:)

0

Jeśli chodzi o najszybsze rozwiązanie to ja bym chyba polecał zaciągnąć to do jakiejś bazki (można te pliki przerobić na inserty jakimś dobrym edytorem tekstu. Zaciągnąć do 2 table (jak pisze przedmówca) i zrobić JOIN i po sprawie. Koniecznie trzeba założyć indeksy po polach po których będziesz się złączał. Przy dobrze założonych indeksach, będzie to myślę czas poniżej sekundy. Jeśli nie SQL, to właśnie takie rozwiązania jak HashTable.

0

Najszybciej chodzilo mi o napisanie kodu, nie dzialanie :) A o sqlu przypomnialem sobie w trakcie pisania kodu php :)

0
johny_bravo napisał(a)

Najszybciej chodzilo mi o napisanie kodu, nie dzialanie :) A o sqlu przypomnialem sobie w trakcie pisania kodu php :)

Faktycznie w tym php to jest tylko pare linijek. Jak pomyśle to w Delphi, musiało by być więcej.

0

A tak przy okazji - duza czesc baz ma mechanizmy importu csv, wiec nawet nie trzeba zamieniac na inserty (choc to nietrudne). Mysql nie potrafi, ale phpMyAdmin juz tak :)

0

johny_bravo dzięki :)

użyłem Twojego kodu, poza drobnymi błedami wszystko tak jak chciałem, trwało kilka sekund, ale rezultat osiągniety, dopiero po filtracji wrzucam to do mysql i wrzucenie 4000 rekordów trwa ok 4 minut, więc rozwiązenie filtracji poprzez mysql nie byłoby dobrym rozwiązaniem, gdyż import 3 mln trwałby kilka godzin

0

No bledy mogly byc, bo pisalem z palca :) Wazne, ze sie przydalo :)

0
b0bik napisał(a)

Koniecznie trzeba założyć indeksy po polach po których będziesz się złączał.

To nie do końca jest takie proste. Jeśli potrzebujesz jeden raz to złączyć, to szybciej będzie bez indeksów. Czas tworzenia indeksów będzie prawdopodobnie większy niż czas wykonania złączenia bez indeksów. Poza tym indeksy niesklastrowane (domyślne) w tym przypadku są o kant d**y potłuc, dobry SZBD je oleje i zrobi BLOCK NESTED LOOP JOIN, który de facto sprowadzi się do algorytmu podanego w kodzie PHP :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1