=?iso-8859-2?q?select_sum_i_dwie_tabele..._b=B3=EAdna_agregac ja?=
kali - Tomasz Kalinowski - 17-02-2007 00:16
=?iso-8859-2?q?select_sum_i_dwie_tabele..._b=B3=EAdna_agregac ja?=
Witam serdecznie, Firebird 2.0 i sql:
Nie wiem czy to dobry pomysł aby prosić o pomoc odnośnie sql, ale widzę że jednak takich postów jest sporo, więc temat jest jednak duży i wymagający wsparcia. Również moje pytanie, będzie po część klonem innych, ale możespróbuję jakoś to uogólnić...
Istnieją dwie tabele, powiązane kluczem Id. W pierwszej tabeli (tab1) klucz jest unikalny, w drugiej tabeli (tab2) może występować kilka razy... np: tab1: Id. grupa stan
tab2:
Id pobrano przyjeto data
tak więc tab1 przechowuje dane na temat stanu (czegoś tam) zaś tab2 dane na temat zmian oraz daty ich zajścia...
należy wykonać zapytanie zwracające sumę stanu, sumę pobrań i sumę przyjęć z datą pomiędzy np styczniem a lutym zgrupowanymi w wg pola tab1.grupa:
select tab1.grupa, tab1.sum(stan), tab2.sum(pobrano), tab2.sum(przyjeto), from tab1 left join tab2 on tab1.Id=tab2.Id where tab2.data between styczen and luty group by tab1.grupa
wiemy, że rekordy w tab1 o danym Id będą niepowtarzalne, w przeciwieństwie do tab2. Tak więc zapytanie to zwróci błędny wynik stanów, ponieważ sum(tab1.stan) zostanie zaagregowane tyle razy, ile jest wystąpień Id w tab2.
Jak rozwiązać problem tego rodzaju? Czyli jak skonstruować zapytanie, aby otrzymać sum(tab1.stan) elementów oczywiście jest to przykład wymyślony ale chyba maksymalnie obrazujący problem. Ja najchętniej zapisałbym to tak:
select tab1.grupa, tab1.sum(stan), (select sum(tab2.pobrano), sum(tab2.przyjeto) from tab2 where tab2.data between styczen and luty) from tab2 left join tab2 on tab1.id=tab2.id group by tab1.grupa)
hm, ale niestety tym sposobem nie pogrupujemy tab2 względem tab1.grupa, nie mówiąc już o tym, że nie może być wynikiem podzapytania kilka kolumn i tak dalej....
Jak rozwiązać problem tego typu? Może przykłady
Z góry dziękuje cierpliwym za pomoc
jak rozwiązać coś takiego?
=?ISO-8859-2?Q?Pawe=B3_Matejski?= - 17-02-2007 00:16
kali - Tomasz Kalinowski wrote: > > select > tab1.grupa, > tab1.sum(stan), > tab2.sum(pobrano), > tab2.sum(przyjeto), > from tab1 > left join tab2 on tab1.Id=tab2.Id > where tab2.data between styczen and luty > group by tab1.grupa > > wiemy, że rekordy w tab1 o danym Id będą niepowtarzalne, w > przeciwieństwie do tab2. Tak więc zapytanie to zwróci błędny wynik > stanów, ponieważ sum(tab1.stan) zostanie zaagregowane tyle razy, ile > jest wystąpień Id w tab2. > > Jak rozwiązać problem tego rodzaju? Czyli jak skonstruować zapytanie, > aby otrzymać sum(tab1.stan) elementów > oczywiście jest to przykład wymyślony ale chyba maksymalnie obrazujący > problem. Ja najchętniej zapisałbym to tak:
Kiepsko - jak według Ciebie sumować stan?
działa niedziała działa wyłączony
Ile wynosi suma tego?!
> select > tab1.grupa, > tab1.sum(stan), > (select sum(tab2.pobrano), sum(tab2.przyjeto) from tab2 where > tab2.data between styczen and luty) > from tab2 > left join tab2 on tab1.id=tab2.id group by tab1.grupa) > > hm, ale niestety tym sposobem nie pogrupujemy tab2 względem > tab1.grupa, nie mówiąc już o tym, że nie może być wynikiem > podzapytania kilka kolumn i tak dalej....
A po co łączysz po id? To nie ma znaczenia. Zgrupuj podzapytanie po grupie i łącz po grupie.
-- P.M.
Rafal \(sxat\) - 17-02-2007 00:16
> > select > > tab1.grupa, > > tab1.sum(stan), > > tab2.sum(pobrano), > > tab2.sum(przyjeto), > > from tab1 > > left join tab2 on tab1.Id=tab2.Id > > where tab2.data between styczen and luty > > group by tab1.grupa
pokaz strukture tabelki, przykladowe dane i jaki chcesz osiagnac wynik i jaka baza danych
pozdr Rafal
kali - Tomasz Kalinowski - 17-02-2007 00:16
=?iso-8859-2?q?Re:_select_sum_i_dwie_tabele..._b=B3=EAdna_agr egacja?=
On 16 Lut, 12:50, Paweł Matejski <m...@spam.madej.pl.eu.org> wrote: > kali - Tomasz Kalinowski wrote: > > > > > > > > > select > > tab1.grupa, > > tab1.sum(stan), > > tab2.sum(pobrano), > > tab2.sum(przyjeto), > > from tab1 > > left join tab2 on tab1.Id=tab2.Id > > where tab2.data between styczen and luty > > group by tab1.grupa > > > wiemy, że rekordy w tab1 o danym Id będą niepowtarzalne, w > > przeciwieństwie do tab2. Tak więc zapytanie to zwróci błędny wynik > > stanów, ponieważ sum(tab1.stan) zostanie zaagregowane tyle razy, ile > > jest wystąpień Id w tab2. > > > Jak rozwiązać problem tego rodzaju? Czyli jak skonstruować zapytanie, > > aby otrzymać sum(tab1.stan) elementów > > oczywiście jest to przykład wymyślony ale chyba maksymalnie obrazujący > > problem. Ja najchętniej zapisałbym to tak: > > Kiepsko - jak według Ciebie sumować stan? > > działa > niedziała > działa > wyłączony > > Ile wynosi suma tego?! > > > select > > tab1.grupa, > > tab1.sum(stan), > > (select sum(tab2.pobrano), sum(tab2.przyjeto) from tab2 where > > tab2.data between styczen and luty) > > from tab2 > > left join tab2 on tab1.id=tab2.id group by tab1.grupa) > > > hm, ale niestety tym sposobem nie pogrupujemy tab2 względem > > tab1.grupa, nie mówiąc już o tym, że nie może być wynikiem > > podzapytania kilka kolumn i tak dalej.... > > A po co łączysz po id? To nie ma znaczenia. Zgrupuj podzapytanie po grupie i > łącz po grupie. > > -- > P.M.- Ukryj cytowany tekst - > > - Pokaż cytowany tekst -
Tak jak myslałem. Nie chodzi o sens sumowania stanu jako stanu, a poprostu pola, które ma cośtam odzwierciedlać...(wszystkie pola: stan, przyjeto, pobrano to pola liczbowe)
a propos łączenia po Id. Nie wiem czy zauważyłeś, ale chcemy wyodrębnić dane z datą z pewnego okresu zapisane w jednej tabeli, i opisem tych danych zawartym w drugiej. Czyli, widać że grupa istnieje tylko w tab1. Nie ma jej w tab2. możemy wiedziec do jakiej grupy należy jedynie poprzez odwołanie do tab1 po Id. pozdr ps. dzieki...
kali - Tomasz Kalinowski - 17-02-2007 00:16
=?iso-8859-2?q?Re:_select_sum_i_dwie_tabele..._b=B3=EAdna_agr egacja?=
On 16 Lut, 12:59, "Rafal \(sxat\)" <gon...@op.pl> wrote: > > > select > > > tab1.grupa, > > > tab1.sum(stan), > > > tab2.sum(pobrano), > > > tab2.sum(przyjeto), > > > from tab1 > > > left join tab2 on tab1.Id=tab2.Id > > > where tab2.data between styczen and luty > > > group by tab1.grupa > > pokaz strukture tabelki, przykladowe dane i jaki chcesz osiagnac wynik i > jaka baza danych > > pozdr > Rafal Dzięki Rafał, że zechciałeś się zgłębić... o to przykład danych: (nie wnikaj w sens, ponieważ brutto w tab2 jest uwarunkowane aplikacją, i dokładnie tak ma być...)
tab1: Id operacja do opearcji braki operacjie braki inne data 1 cięcie 10 0 1 2007-02-01 1 wiercenie 9 0 5 2007-01-01 ! 2 ciecie 10 1 0 2007-02-15 2 ciecie 10 3 3 2007-02-14 3 szlifowanie 20 0 2 2007-02-20 3 wiercenie 20 1 1 2007-01-02 ! tab2
Id grupa brutto 1 rurka 10 2 rurka 10 - 3 szyna 20
wynik: select sum z tab1 i sum z tab2 gdzie data tab1 zawiera się w przedziale luty 2007 (wykrzyknikami oznaczyłem niepasujące dane) i pogrupowane w grupy z tab2. Jedyny klucz to ID
grupa brutto braki rurka 20 8 suma z tab2 kolumny brutto pod warunkiem że id zawiera się w tabeli1 i pasuje do warunku daty oraz suma braków z tab2 z tym samym warunkiem szyna 20 2
miłego dnia,
=?ISO-8859-2?Q?Pawe=B3_Matejski?= - 17-02-2007 00:16
kali - Tomasz Kalinowski wrote: >> >> działa >> niedziała >> działa >> wyłączony >> >> Ile wynosi suma tego?! >> >>> select >>> tab1.grupa, >>> tab1.sum(stan), >>> (select sum(tab2.pobrano), sum(tab2.przyjeto) from tab2 where >>> tab2.data between styczen and luty) >>> from tab2 >>> left join tab2 on tab1.id=tab2.id group by tab1.grupa) >>> hm, ale niestety tym sposobem nie pogrupujemy tab2 względem >>> tab1.grupa, nie mówiąc już o tym, że nie może być wynikiem >>> podzapytania kilka kolumn i tak dalej.... >> A po co łączysz po id? To nie ma znaczenia. Zgrupuj podzapytanie po grupie i >> łącz po grupie. >> >> -- >> P.M.- Ukryj cytowany tekst - >> >> - Pokaż cytowany tekst - > > Tak jak myslałem. > Nie chodzi o sens sumowania stanu jako stanu, a poprostu pola, które > ma cośtam odzwierciedlać...(wszystkie pola: stan, przyjeto, pobrano to > pola liczbowe)
No przyznaje, że też kalpki na moich oczach sie pojawiły i jakoś zawęziłem znaczenie słowa stan. Ale jakbys podał brutto, to uniknelibysmy nieporozumień. ;)
> a propos łączenia po Id. Nie wiem czy zauważyłeś, ale chcemy > wyodrębnić dane z datą z pewnego okresu zapisane w jednej tabeli, i > opisem tych danych zawartym w drugiej. Czyli, widać że grupa istnieje > tylko w tab1. Nie ma jej w tab2. możemy wiedziec do jakiej grupy > należy jedynie poprzez odwołanie do tab1 po Id. pozdr > ps. dzieki...
Ach... tu też coś za pobieżnie sie mu przyglądnąłem i zmylił mnie niesparowany nawias na końcu. Tak w zasadzie, to wogóle miszmasz z tego zapytania, bo jeszcze na końcu łaczysz left joinem tabele samą ze sobą. :)
To jeszcze raz.
select tab1.grupa, tab1.sum(stan), (select sum(tab2.pobrano), sum(tab2.przyjeto) from tab2 where tab2.data between styczen and luty) -- tu nie nie wiążesz rekordów z tab2 z tab1!!! from tab2 left join tab2 on tab1.id=tab2.id group by tab1.grupa -- a tu skolei niepotrzebnie robisz relacje.
W efekcie powinno wyglądać tak:
select tab1.grupa,tab1.sum(stan), (select sum(tab2.pobrano), sum(tab2.przyjeto) from tab2 where tab2.id = tab1.id and tab2.data between styczen and luty) from tab1 group by tab1.grupa
Tak się zastanawiam, czy można w tym miejscu wstawiać subselekta w tym miejcu w FB. Ale to i tak nie ważne, bo dużo lepsze zapytanie moim zdaniem to:
select tab1.grupa,tab1.sum(stan), s.sum_przyjeto,s.sum_pobrano from tab1 left join (select tab2.id, sum(tab2.pobrano) as sum_pobrano, sum(tab2.przyjeto) as sum_przyjeto from tab2 where tab2.data between styczen and luty group by tab2.id ) as s on (tab1.id = s.id) group by tab1.grupa
-- P.M.
kali - Tomasz Kalinowski - 20-02-2007 00:03
=?iso-8859-2?q?Re:_select_sum_i_dwie_tabele..._b=B3=EAdna_agr egacja?=
>P.M.
Wielkie dzięki za zagłębienie się w zapytanie. Przepraszam za błędy. Rzeczywiście nie dopatrzyłem tych szczegułów (ale to tylko przykład). Zawsze się zastanawiam, co zrobić, aby pytanie odnośnie składni sql, można było przedstawić na forum w takiej postaci, aby wszyscy mogli je zrozumieć i nie musieli się zastanawiać nad strukturą tabel.... ;) cóż, to są jednak zbyt indywidualne rzeczy (tabele). Jeszcze raz dziękuję za pomoc, zaraz siadam do testowania... Jeżeli chodzi o subselecty w FB od v 2.0 jest to już możliwe.....
pozdrawiam, - Tomasz Kalinowski
zanotowane.pldoc.pisz.plpdf.pisz.pleffulla.pev.pl
|
Wydajność baz danych w zależności od poziomu izolacji ANSI/ISO
Czy zna (obsługuje) ktoś program Iso Draw ?
MYSQL - kodowanie w ISO-PL
strona plus baza w iso do utf-8
Kodowanie: z iso na utf
Konwesja znaków w dump'ie bazy danych - ISO -> utf-8 -> ISO -> utf-8
=?iso-8859-2?q?Informatyka,_Java,_EJB,_Ajax,_Spring=2E_Czy=BF by_to_koniec_=B6wiata,_czy_te=BF_nasze_uczelnie_b= EAd=B1_uczy=B3y_w_ko=F1cu!_czego_praktycznego_=2E= 2E=2E=2E?=
=?iso-8859-2?q?Ati_Mobility_Radeon_X300_W_Notebooku_Jak_Zwi=E Akszy=E6_Ilo=B6=E6_Grafiki_Poprzez_Wsp=F3=B3dziele nie_Z_Ramu=3F=3F=3F?=
=?ISO-8859-2?Q?=AFegnam_si=EA=2E=2E=2E?=
Manager =?ISO-8859-2?Q?font=F3w=2E=2E=2E?=
zanotowane.pldoc.pisz.plpdf.pisz.pllunadance.htw.pl
Cytat
Decede mihi sole - nie zasłaniaj mi słonca. Gdy kogoś kochasz, jesteś jak stworzyciel świata - na cokolwiek spojrzysz, nabiera to kształtu, wypełnia się barwą, światłem. Powietrze przytula się do ciebie, choćby był mróz, a ty masz w sobie tyle radości, że musisz ją rozdawać wokoło, bo się w tobie nie mieści Hoc fac - tak czyń. A tergo - od tyłu; z tyłu. I czarne włosy posiwieją. Safona |
|