Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Import i sumowanie istniejących CSV
Forum PHP.pl > Forum > Bazy danych > MySQL
banki
Witam wszystkich,

mam problem z importem pliku CSV do bazy danych. Oczywiście zwykłe importowanie działa, ale nie zadowala mnie wynik tego importu.

Załóżmy że mam plik CSV wyglądający tak:
3504,72.00,011179239474,U23947,"nazwa 1"
3506,72.00,011179238910,U23891,"nazwa 2"
3508,72.00,011179238828,U23882,"nazwa 3"
3506,22.00,011179238910,U23891,"nazwa 2"

Jak widać 2 i 4 wiersz jest taki sam, różni się jedynie drugą kolumną. W moim kodzie importuje się jednak tylko jeden wiersz, ten, który jest wyżej. W tym wypadku 4 wiersz jest pomijany. Zwracane jest coś takiego:
3504,72.00,011179239474,U23947,"nazwa 1"
3506,72.00,011179238910,U23891,"nazwa 2"
3508,72.00,011179238828,U23882,"nazwa 3"

Efekt jaki chcę osiągnąć to:
3504,72.00,011179239474,U23947,"nazwa 1"
3506,94.00,011179238910,U23891,"nazwa 2"
3508,72.00,011179238828,U23882,"nazwa 3"

Czyli wartość np. z 2 kolumny się sumowała. 1 kolumna jest unikalna i niepowtarzalna, więc rekordy, które mają tą samą liczbę w kolumnie 1 powinny sumować wynik z kolumny 2. Nie wiem czy jasno wytłumaczyłem.

Do tej pory używałem do importu takiego kodu:
  1. <?php
  2. include 'dbConfig.php';
  3. if(isset($_POST['importSubmit'])){
  4. $csvMimes = array('text/x-comma-separated-values', 'text/comma-separated-values', 'application/octet-stream', 'application/vnd.ms-excel', 'application/x-csv', 'text/x-csv', 'text/csv', 'application/csv', 'application/excel', 'application/vnd.msexcel', 'text/plain');
  5. if(!empty($_FILES['file']['name']) && in_array($_FILES['file']['type'],$csvMimes)){
  6. if(is_uploaded_file($_FILES['file']['tmp_name'])){
  7.  
  8. $csvFile = fopen($_FILES['file']['tmp_name'], 'r');
  9. fgetcsv($csvFile);
  10. while(($line = fgetcsv($csvFile)) !== FALSE){
  11. $db->query("INSERT INTO produkty (numer, ilosc, ean, kod1, nazwa) VALUES ('".$line[0]."','".$line[1]."','".$line[2]."','".$line[3]."','".$line[4]."','".$line[5]."')");
  12. }
  13. fclose($csvFile);
  14. $qstring = '?status=sukces';
  15. }else{
  16. $qstring = '?status=error';
  17. }
  18. }else{
  19. $qstring = '?status=nieprawidlowy_plik';
  20. }
  21. }
  22. header("Location: index.php".$qstring);
  23. ?>



Z góry dzięki za jakiekolwiek podpowiedzi.
banki
Dzięki za nakierowanie.

Poczytałem trochę o tym i poprawiłem kod, który jednak nie działa. Efekt jest taki sam.

  1. <?php
  2. include 'dbConfig.php';
  3. if(isset($_POST['importSubmit'])){
  4. $csvMimes = array('text/x-comma-separated-values', 'text/comma-separated-values', 'application/octet-stream', 'application/vnd.ms-excel', 'application/x-csv', 'text/x-csv', 'text/csv', 'application/csv', 'application/excel', 'application/vnd.msexcel', 'text/plain');
  5. if(!empty($_FILES['file']['name']) && in_array($_FILES['file']['type'],$csvMimes)){
  6. if(is_uploaded_file($_FILES['file']['tmp_name'])){
  7.  
  8. $csvFile = fopen($_FILES['file']['tmp_name'], 'r');
  9. fgetcsv($csvFile);
  10. while(($line = fgetcsv($csvFile)) !== FALSE){
  11. $db->query("INSERT INTO produkty (numer, ilosc, ean, kod1, nazwa) VALUES ('".$line[0]."','".$line[1]."','".$line[2]."','".$line[3]."','".$line[4]."','".$line[5]."')
  12. ON DUPLICATE KEY UPDATE ilosc = VALUES(ilosc)"
  13. ");
  14. }
  15. fclose($csvFile);
  16. $qstring = '?status=sukces';
  17. }else{
  18. $qstring = '?status=error';
  19. }
  20. }else{
  21. $qstring = '?status=nieprawidlowy_plik';
  22. }
  23. }
  24. header("Location: index.php".$qstring);
  25. ?>


dodałem do kodu
"ON DUPLICATE KEY UPDATE ilosc = VALUES(ilosc)"
myślałem że to zsumuje wartości kolumny ilosc dla klucza numer a tak na prawdę różnicy nie ma żadnej.
nospor
Tak sie w mysql dodaje wartosci:
pole = pole + 5
gdzie 5 to wartosc 5 ktora chcesz dodac do pola pole.

Podobnie sie sumuje w kazdym innym czy to jezyku czy to bazie danych.


Zas
pole = 5
zawsze nadpisuje wartosc pola pole wartoscia 5. To jest dosc logiczne i dziala tak samo rowniez wszedzie
banki
Tak faktycznie, głupio trochę to napisałem. W tej chwili ostatnią wartość dodaje z listy. Tylko jak zrobić sumowanie wszystkich liczb z kolumny dla jednego KEYa? Próbowałem z SUM lecz nie przechodziło
nospor
No przeciez w poprzednim poscie ci napisalem jak sie SUMUJE. Ty zas masz tam ciagle nadpisywanie temu ci wpisuje ostatnia wartosc. Zmien na to co ci napisalem.
banki
No tak, tylko że ja nie wiem jaka tam będzie wartość dodana i nie mogę zrobić sobie +1, +2 czy +10. Może być 20 a może być i 30. Plik CSV, który importuje może mieć 3 wartości z jednym kluczem.

Mogę mieć CSV który wygląda tak:
3504,72.00,011179239474,U23947,"nazwa 1"
3506,72.00,011179238910,U23891,"nazwa 2"
3508,72.00,011179238828,U23882,"nazwa 3"
3506,22.00,011179238910,U23891,"nazwa 2"

i wynik dla 3506 musi być 94 (dla 2 kolumny), a inny CSV może mieć
3504,72.00,011179239474,U23947,"nazwa 1"
3506,72.00,011179238910,U23891,"nazwa 2"
3508,72.00,011179238828,U23882,"nazwa 3"
3506,22.00,011179238910,U23891,"nazwa 2"
3506,22.00,011179238910,U23891,"nazwa 2"
i wtedy wynik musi mieć 116
mmmmmmm
ON DUPLICATE KEY UPDATE ilosc = ilosc + VALUES(ilosc)
a dla pewności
ON DUPLICATE KEY UPDATE ilosc = Coalesce(ilosc, 0) + VALUES(Coalesce(ilosc,0))
banki
u mnie zadziałało to:

ON DUPLICATE KEY UPDATE ilosc = ilosc+$line[1]

z VALUES i z Coalesce() nic się nie dzieje

Pojawił się przy tym kolejny problem. Problemem jest jeśli plik CSV jest oddzielany średnikiem ; a nie przecinkiem.

Zmieniając fgetcsv($csvFile) na fgetcsv($csvFile, 0, ';') aby rozdzielało po średnikach, wali się wszystko. Nie wczytuje w ogóle do bazy nic.

Usuwając ON DUPLICATE KEY UPDATE ładuje się plik ze średnikami. Wygląda jakby ON DUPLICATE KEY UPDATE kolidował ze średnikami ... możliwe?
Pyton_000
Nie. Wyświetl sobie wygenerowane zapytanie to będziesz wiedział dlaczego się sypie.
banki
Ok, udało się. Dzięki wszystkim za pomoc.

Końcowo kod wygląda tak:

  1. <?php
  2. include 'dbConfig.php';
  3. if(isset($_POST['importSubmit'])){
  4. $csvMimes = array('text/x-comma-separated-values', 'text/comma-separated-values', 'application/octet-stream', 'application/vnd.ms-excel', 'application/x-csv', 'text/x-csv', 'text/csv', 'application/csv', 'application/excel', 'application/vnd.msexcel', 'text/plain');
  5. if(!empty($_FILES['file']['name']) && in_array($_FILES['file']['type'],$csvMimes)){
  6. if(is_uploaded_file($_FILES['file']['tmp_name'])){
  7.  
  8. $csvFile = fopen($_FILES['file']['tmp_name'], 'r');
  9. fgetcsv($csvFile);
  10. while(($line = fgetcsv($csvFile, 0, ';')) !== FALSE){
  11. $db->query("INSERT INTO produkty (numer, ilosc, ean, kod1, nazwa) VALUES ('".$line[0]."','".$line[1]."','".$line[2]."','".$line[3]."','".$line[4]."','".$line[5]."')
  12.  
  13. ON DUPLICATE KEY UPDATE ilosc = ilosc+'".$line[1]."'
  14. ");
  15. }
  16. fclose($csvFile);
  17. $qstring = '?status=sukces';
  18. }else{
  19. $qstring = '?status=error';
  20. }
  21. }else{
  22. $qstring = '?status=nieprawidlowy_plik';
  23. }
  24. }
  25. header("Location: index.php".$qstring);
  26. ?>
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.