Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Import i sumowanie istniejących CSV
banki
post 26.06.2018, 22:55:16
Post #1





Grupa: Zarejestrowani
Postów: 109
Pomógł: 1
Dołączył: 23.11.2007

Ostrzeżenie: (0%)
-----


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.

Ten post edytował banki 26.06.2018, 22:56:57
Go to the top of the page
+Quote Post
mmmmmmm
post 27.06.2018, 07:13:30
Post #2





Grupa: Zarejestrowani
Postów: 1 421
Pomógł: 310
Dołączył: 18.04.2012

Ostrzeżenie: (0%)
-----


https://dev.mysql.com/doc/refman/8.0/en/ins...-duplicate.html
Go to the top of the page
+Quote Post
banki
post 27.06.2018, 16:25:59
Post #3





Grupa: Zarejestrowani
Postów: 109
Pomógł: 1
Dołączył: 23.11.2007

Ostrzeżenie: (0%)
-----


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.
Go to the top of the page
+Quote Post
nospor
post 27.06.2018, 16:30:00
Post #4





Grupa: Moderatorzy
Postów: 36 440
Pomógł: 6290
Dołączył: 27.12.2004




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


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
banki
post 27.06.2018, 16:57:36
Post #5





Grupa: Zarejestrowani
Postów: 109
Pomógł: 1
Dołączył: 23.11.2007

Ostrzeżenie: (0%)
-----


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
Go to the top of the page
+Quote Post
nospor
post 27.06.2018, 17:00:07
Post #6





Grupa: Moderatorzy
Postów: 36 440
Pomógł: 6290
Dołączył: 27.12.2004




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.


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
banki
post 27.06.2018, 17:47:09
Post #7





Grupa: Zarejestrowani
Postów: 109
Pomógł: 1
Dołączył: 23.11.2007

Ostrzeżenie: (0%)
-----


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
Go to the top of the page
+Quote Post
mmmmmmm
post 28.06.2018, 07:21:55
Post #8





Grupa: Zarejestrowani
Postów: 1 421
Pomógł: 310
Dołączył: 18.04.2012

Ostrzeżenie: (0%)
-----


ON DUPLICATE KEY UPDATE ilosc = ilosc + VALUES(ilosc)
a dla pewności
ON DUPLICATE KEY UPDATE ilosc = Coalesce(ilosc, 0) + VALUES(Coalesce(ilosc,0))
Go to the top of the page
+Quote Post
banki
post 28.06.2018, 09:07:09
Post #9





Grupa: Zarejestrowani
Postów: 109
Pomógł: 1
Dołączył: 23.11.2007

Ostrzeżenie: (0%)
-----


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?
Go to the top of the page
+Quote Post
Pyton_000
post 28.06.2018, 09:18:13
Post #10





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

Ostrzeżenie: (0%)
-----


Nie. Wyświetl sobie wygenerowane zapytanie to będziesz wiedział dlaczego się sypie.
Go to the top of the page
+Quote Post
banki
post 28.06.2018, 09:23:43
Post #11





Grupa: Zarejestrowani
Postów: 109
Pomógł: 1
Dołączył: 23.11.2007

Ostrzeżenie: (0%)
-----


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. ?>
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 28.03.2024 - 11:58