Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Suma kosztow
Forum PHP.pl > Forum > Bazy danych
beeper
Potrzebuje zrobic zestawnienie kosztow
Ma sie wyswietlic dane o umowie i suma kosztow dla kazdej z nich

Sa 3 tabele:
Umowa
KosztyFin
KosztySad

i robie tak:
  1. SELECT w IDumowy
  2. , w.WNazwaSkrocona
  3. , w.DNazwaSkrocona
  4. , sum(wf.Kwota) AS SumKwotaFin , sum(ws.Kwota) AS SumKwotaSad
  5. FROM Umowa w
  6. LEFT JOIN KosztyFin wf ON w.IDumowy=wf.IDumowy
  7. LEFT JOIN KosztySad ws ON w.IDumowy=ws.IDumowy
  8. GROUP BY w.IDumowy

Niestety zle mi wylicza, kosztyFin wynosza 4012 a wylicza mi ze 170129,95

Nie mam pojecia skad sie to bierze.

Porszę o pomoc.
Jabol
hmm... a sprawdzałeś obiawy? Skąd się bierze liczba 17.....cośtam? Czego jest sumą (wszystkich umów, czy jak?). Wylicza źle dla każdej umowy czy tylko dla jednej?
beeper
Sprawdzalem i w bazie wszystko wyglada wporzadku, nie wiem czemu to zle liczy dla wszystkich rekordow, inne sumy tez zle

Jeżeli robię np:
  1. SELECT sum(Kwota)
  2. FROM kosztyf<span style='color:green'>in WHERE ID=3

to wynik jest poprawny

Zauwazylem ze jesli lacze wylaczenie dwie tabele to wynik sum jest poprawny, jezeli dodaje następne to wplywa to na wynik, nie za bardzo to rozumiem
nospor
left join ma to do siebie, że dołącza ci też full pustych rekordów, przez co tworzą się sztuczne rekordy do sumowania. Stąd ten przyrost.

musisz dać pare warunków na not null. Coś w tym stylu (zakładam ze masz pole ID w tabelach) (to powinno zmniejszyc sume, ale nie gwarantuje że da wynik poprawny)

  1. SELECT w IDumowy
  2. , w.WNazwaSkrocona
  3. , w.DNazwaSkrocona
  4. , sum(wf.Kwota) AS SumKwotaFin , sum(ws.Kwota) AS SumKwotaSad
  5. FROM Umowa w
  6. LEFT JOIN KosztyFin wf ON w.IDumowy=wf.IDumowy
  7. LEFT JOIN KosztySad ws ON w.IDumowy=ws.IDumowy
  8. WHERE wf.ID IS NOT NULL AND ws.ID IS NOT NULL
  9. GROUP BY w.IDumowy
beeper
Niestety nie dziala :/
Probowalem na innej bazie i działanie jest podobne :/
Mam takie zapytanie, które działa poprawnie
  1. SELECT w.IDwierzyciela
  2. , w.NaleznoscGlowna
  3. , sum(wp.wplatykwota)
  4. , sum(wf.kwota)
  5. , sum(ww.kwota)
  6. FROM windykacja w
  7. LEFT OUTER JOIN wplaty wp USING(IDwierzyciela)
  8. LEFT OUTER JOIN kosztywf wf USING(IDwierzyciela)
  9. GROUP BY w.IDwierzyciela


Ale w momencie kiedy dodaje jeszcze jedno zlaczenie, wynik jest znowu nieprawidlowy :/
  1. SELECT w.IDwierzyciela
  2. , w.NaleznoscGlowna
  3. , sum(wp.wplatykwota)
  4. , sum(wf.kwota)
  5. , sum(ww.kwota)
  6. FROM windykacja w
  7. LEFT OUTER JOIN wplaty wp USING(IDwierzyciela)
  8. LEFT OUTER JOIN kosztywf wf USING(IDwierzyciela)
  9. LEFT OUTER JOIN kosztyww ww USING(IDwierzyciela)
  10. GROUP BY w.IDwierzyciela
SongoQ
Moze idz tropem @nospor i daj konwersje z NULL na 0 w sumowaniu
sum(null_na_0 (wp.wplatykwota)) - wstaw funkcje odpowiednia do danej bazy bo nie zauwazylem do jakiej bazki sie Twoje zapytanie odnosi.


A jesli nie zadziala wrzuc strukture napisz jaka baza i podaj kilka rekordow.
beeper
Tak wyglada diagram tabel ktore mnie interesuja

Jezeli robie osobno dla kosztowwf i ww
  1. SELECT Idwierzyciela, sum(kwota)
  2. FROM kosztywf GROUP BY idwierzyciela

Wynik jest poprawny i wyglada tak


To samo dla wplat
  1. SELECT Idwierzyciela, sum(wplatykwota)
  2. FROM wplaty GROUP BY idwierzyciela



Jezeli zrobie tak:
  1. SELECT w.IDwierzyciela
  2. , w.NaleznoscGlowna
  3. , sum(wp.wplatykwota)
  4. , sum(wf.kwota)
  5. FROM windykacja w
  6. LEFT OUTER JOIN wplaty wp USING(IDwierzyciela)
  7. LEFT OUTER JOIN kosztywf wf USING(IDwierzyciela)
  8. GROUP BY w.IDwierzyciela

to wszystko gra i dobrze liczy


Ale jak dodam kolejna tabele to juz sie sypie
  1. SELECT w.IDwierzyciela
  2. , w.NaleznoscGlowna
  3. , sum(wp.wplatykwota)
  4. , sum(wf.kwota)
  5. , sum(ww.kwota)
  6. FROM windykacja w
  7. LEFT OUTER JOIN wplaty wp USING(IDwierzyciela)
  8. LEFT OUTER JOIN kosztywf wf USING(IDwierzyciela)
  9. LEFT OUTER JOIN kosztyww ww USING(IDwierzyciela)
  10. GROUP BY w.IDwierzyciela


SongoQ
Moze jakis blad jest z using. Sprawdz przez LEFT JOIN i warunek zlaczenia w ON. Moze cos pomoze.

Mozesz tez sprawdzic jakie rekordy chce Ci sumowac dla id = 3, wywal grupowanie i sprawdz, bo skas ten blad musi byc.
beeper
Z tego co dzis probowalem to wyglada na to ze mysql sobie cos nie radzi z laczeniem wielu tabel.
SongoQ
Sprawdzales tak jak Ci pisalem, 3 tabele przez LEFT JOIN i warunek w ON zobacz czy zadziala.

A bez grupowania robi Ci jakies wielokrotnosci? Czy laczy jakies niepozadane rekordy czy co?? Jakas przyczyna musi byc.
beeper
Przez ON juz probowalem, efekt taki sam.
Nie mam pojecia czemu tak sie dzieje, zawsze jak dorzucam 3 tabele to sie sypie.
Bez grupowania nie pojdzie bo wywala blad
"Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause"


Zauwazylem ze wszystkie inne kolumny sa mnożone x4 razy za wyjatkiem kolumny koszty z tabeli kosztyww.
Zaczalem z generatorow kozystac, wiec nie wiem co moze byc zle. Dane w bazie? ale jak ?

Wg mnie to zapytanie powinno poprawnie dzialac, ale gdzie jest blad to nie wiem
  1. SELECT
  2. windykacja.IDwierzyciela,
  3. SUM(kosztywf.Kwota) AS KwotaWF,
  4. SUM(kosztyww.Kwota) AS KwotaWW,
  5. SUM(wplaty.WplatyKwota) AS KwotaWplaty
  6. FROM windykacja LEFT OUTER JOIN kosztywf ON (windykacja.IDwierzyciela=kosztywf.IDwierzyciela)
  7. LEFT OUTER JOIN kosztyww ON (windykacja.IDwierzyciela=kosztyww.IDwierzyciela)
  8. LEFT OUTER JOIN wplaty ON (windykacja.IDwierzyciela=wplaty.IDwierzyciela)
  9. GROUP BY windykacja.IDwierzyciela
SongoQ
  1. SELECT
  2. windykacja.IDwierzyciela,
  3. kosztywf.Kwota AS KwotaWF,
  4. kosztyww.Kwota AS KwotaWW,
  5. wplaty.WplatyKwota AS KwotaWplaty
  6. FROM windykacja LEFT JOIN kosztywf ON (windykacja.IDwierzyciela=kosztywf.IDwierzyciela)
  7. LEFT JOIN kosztyww ON (windykacja.IDwierzyciela=kosztyww.IDwierzyciela)
  8. LEFT JOIN wplaty ON (windykacja.IDwierzyciela=wplaty.IDwierzyciela)
  9. WHERE windykacja.IDwierzyciela = 3


Sprawdz co to Ci zwroci, czy jak zsumujesz recznie to bedzie ok?
beeper
No teraz jest ok.


A tutaj wartosci na ktore sie to sklada


Widac ze w grupowaniu sie to wysypuje, nie mam pojecia jak to teraz zrobic
SongoQ
A nie pisze nic na stronie MySQLa, ze w tej wersji i w tym jest blad??

Dziwne troszeczke sad.gif
beeper
Chyba jednak to nie jest wina mysql. Wrzucilem baze do MSSQL'a i wynik jest taki sam.
Takze teraz juz nie mam pojecia co z tym zrobic.
Jabol
Odpowiedź jest bardzo prosta: musisz policzyć każdą wartość odzielnie. Wiem, że to troszkę nieestetyczne objeście, ale rzeczywiście LEFT JOIN generuje Ci dużo g.
SongoQ
@Jabol Nie wiem co sie kryje pod tym "g" ale wydaje mi sie ze jak by cos LEFT JOIN nieprawidlowo dzialal to by generowal za kazdym razem inne rekordy, jesli wyniki sa dokladnie takie same w 2 bazach danych to wydaje mi sie ze to wina jest zapytania.

@beeper Jak bys mogl to barzo prosze o zrzut SQL struktury i danych najlepiej na @, chce cos pokombinowac.
Jabol
Cytat(SongoQ @ 2005-07-20 21:10:05)
@Jabol Nie wiem co sie kryje pod tym "g" ale wydaje mi sie ze jak by cos LEFT JOIN nieprawidlowo dzialal to by generowal za kazdym razem inne rekordy, jesli wyniki sa dokladnie takie same w 2 bazach danych to wydaje mi sie ze to wina jest zapytania.

@SongoQAleż left join działa znakomicie. Dokładnie tak jak trzeba. Po prostu służy do innych zastosowań, a w tym konkretnym przypadku generuje wiele "g.", czyli niepotrzebnych w tym zastosowaniu rekordów. Bo on nie robi tego "całościowo". On tutaj kleji każdy rekord oddzielnie i nie patrzy, czy już z niego korzystał.

@beeper: popróbuj z widokami (tutaj schowane)
Kod
SELECT win.id, kw1.kw, kw2.kw, kw3.kw
FROM win
LEFT JOIN (SELECT id, sum(kwota1) AS kw FROM kwota1 GROUP BY  id) AS kw1 ON (win.id=kw1.id)
LEFT JOIN (SELECT id, sum(kwota2) AS kw FROM kwota2 GROUP BY  id) AS kw2 ON (win.id=kw2.id)
LEFT JOIN (SELECT id, sum(kwota3) AS kw FROM kwota3 GROUP BY  id) AS kw3 ON (win.id=kw3.id);

Czy jak to się tam nazywa - podzapytania. Ale możesz te podzapytania wyprowadzić do widoków i będzie ok (podzapytania w ten sposób działają na pgsql'u, ale ze to na mysql'u pójdzie nie ręcze, a widoki chyba nawet mysql ma).
Acha, nazwy tabel to sobie wymyśliłem jak przenosiłem strukturę na lokala. win to windykacja, kwota1 to kosztywf, kwota2 to kosztyww a kwota3 to wpłaty (czy jakkolwiek w dowolnej kolejości).


XXX: DAŁEM CODE, bo SQL nie działa (wywala mi jakieś fragmenty html'a);
beeper
Dzieki wielkie wszystkim za pomoc.
Oto rozwiazanie winksmiley.jpg
  1. SELECT
  2. windykacja.IDwierzyciela,
  3. (
  4. SELECT SUM(kosztywf.Kwota)
  5. FROM kosztywf WHERE kosztywf.idwierzyciela = windykacja.idwierzyciela
  6. GROUP BY kosztywf.IDwierzyciela
  7. ) AS KosztyWfSum,
  8. (
  9. SELECT SUM(kosztyww.Kwota)
  10. FROM kosztyww WHERE kosztyww.idwierzyciela = windykacja.idwierzyciela
  11. GROUP BY kosztyww.IDwierzyciela
  12. ) AS KosztyWWSum,
  13. (
  14. SELECT SUM(wplaty.WplatyKwota)
  15. FROM wplaty WHERE wplaty.idwierzyciela = windykacja.idwierzyciela
  16. GROUP BY wplaty.IDwierzyciela
  17. ) AS WplatySum
  18. FROM windykacja
SongoQ
@Jabol
Cytat
@beeper: popróbuj z widokami (tutaj schowane)

Widoki to zupelnie inna sprawa, tak naprawde tutaj chodzi jak juz pozniej napisales podzapytania (podselecty). Widok to tak naprawde zapytanie zapisanie w bazie danych, jak jest zapytnie do widoku wykonywane to jest wykonywane dolaczania zapytania i optymalizacja.

Bardzo czesto stosuje widoki, ulatwiaja sprawe. Drobna zmiana modyfikuje w jednym miejscu widok i caly system dziala tak jak nalezy, zapominam o kodzie php.
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.