Pogčedajte punu verziju : Sumiranje parova
razno
04. 09. 2011., 20:18
Pozdrav,
imam jedan problem na kome sam zakucao.
Najme imam tabelu Skup_proizvoda(ID1,ID2,broj)
ID1 i ID2 referenciraju tabelu proizvodi. Ono sto treba da uradim je da izbacim sumu brojeva za svaki par. Par se moze pojavljivati vise puta. Takodje pod jednim parom se podrazumeva 1|2 i 2|1
Evo primer podatak
ID1|ID2|broj
------------
1|2|10
2|1|20
1|3|5
Ocekivani rezultat treba da bude
ID1|ID2|BROJ
-------------
1|2|30
1|3|5
Resenje treba da bude cist SQL
webarto
04. 09. 2011., 22:04
SELECT t2.id_1, t2.id_2, SUM(t1.broj) broj
FROM dpt t1
LEFT JOIN dpt t2 ON t1.id_1 = t2.id_2
WHERE t1.id_2 = t2.id_1
id_1 id_2 broj
1 2 30
E sad jedino još da selektuje ove single parove...
jablan
04. 09. 2011., 22:21
Ja bih rađe to uradio sa ugnježđenim upitom da dovedem ID1 i ID2 u red, pa onda nad time običan GROUP BY.
Znači nešto na foru
SELECT id1, id2, sum(broj) FROM
(
SELECT
CASE WHEN id1 > id2 THEN id2 ELSE id1 AS id1,
CASE WHEN id1 > id2 THEN id1 ELSE id2 AS id2,
broj
FROM dpt
) a
GROUP BY id1, id2
razno
05. 09. 2011., 00:51
@webarto Ne ispisuje sve redove, tj ispisuje one koji se javljaju u obe varijante dok oni koji su u jednoj ne ispisuje. Hvala u svakom slucaju na odgovoru
@Jablan da to je to resenje.
Sad vidim kako je prosto, ali kad ti nije dan, nije ti :)
webarto
05. 09. 2011., 19:56
Da, napisao sam to :) @jablan, znaš li ti možda da prepraviš ovaj moj query, a da vraća oba rezultata, ili ovaj suprotni :) Hvala.
jablan
06. 09. 2011., 07:31
Teško bogami. Mislim da nije dobar put. Imaš banalan primer, npr da imaš u tabeli
1 2 10
1 2 10
2 1 10
2 1 10
u JOINU ćeš onda imati 8 redova kao rezultat, tj suma će ti biti 80, a ne 40, zar ne?
ivanhoe
06. 09. 2011., 08:37
evo ovako:
SELECT t1.id1, t1.id2, IF(t2.id1, (t1.broj + t2.broj), t1.broj) AS broj
FROM proba t1
LEFT JOIN proba t2 ON (t1.id1 = t2.id2 AND t1.id2 = t2.id1)
razno
06. 09. 2011., 10:24
@ivanhoe Nece bas raditi kako treba. Radi sumiranje lepo, medjutim ne izbacuje duplikate iz rezultata (sto treba).
I ja sam krenuo da resavam sa join-om medjutim zakucao sam na tom delu izbacivanja duplih rezultata :)
jablan
06. 09. 2011., 10:29
evo ovako:
Nisam siguran da razumem ideju:
test=# create table dpt (id1 integer, id2 integer, broj integer);
CREATE TABLE
test=# insert into dpt values (1, 2, 10);
INSERT 0 1
test=# insert into dpt values (1, 2, 10);
INSERT 0 1
test=# insert into dpt values (2, 1, 10);
INSERT 0 1
test=# insert into dpt values (2, 1, 10);
INSERT 0 1
test=# insert into dpt values (1, 3, 10);
INSERT 0 1
test=# SELECT t1.id1, t1.id2, t1.broj + coalesce(t2.broj, 0) AS broj
FROM dpt t1
LEFT JOIN dpt t2 ON (t1.id1 = t2.id2 AND t1.id2 = t2.id1);
id1 | id2 | broj
-----+-----+------
1 | 2 | 20
1 | 2 | 20
1 | 2 | 20
1 | 2 | 20
1 | 3 | 10
2 | 1 | 20
2 | 1 | 20
2 | 1 | 20
2 | 1 | 20
(9 rows)
ivanhoe
06. 09. 2011., 14:58
da, da, nisam pazljivo procitao opis, ne resava se duplikata... mada mora da ima neka fora i ovako, trebalo bi da (skoro) svaki subquery moze da se resi i JOIN-om
EDIT: Evo ovo radi:
SELECT t1.`id1`, t1.id2, t1.broj + coalesce(t2.broj, 0) AS broj
FROM proba t1
LEFT JOIN proba t2 ON (t1.id1 = t2.id2 AND t1.id2 = t2.id1)
GROUP BY IF(t1.id1<t1.id2, t1.id1, t1.id2), IF(t1.id1 > t1.id2, t1.id1, t1.id2)
jablan
06. 09. 2011., 15:25
Jesi li siguran da to daje dobre cifre? Nemam MySQL da probam, a Postgres ne dozvoljava da u SELECT imaš nešto što nemaš u GROUP BY (osim ako nije agregatna funkcija). Zar ne treba da postoji neki SUM()?
webarto
06. 09. 2011., 15:33
Radi ovo od @ivanhoe dobro...
1 2 30
1 3 5
jablan
06. 09. 2011., 15:52
Mislio sam na moj primer podataka:
test=# insert into dpt values (1, 2, 10);
INSERT 0 1
test=# insert into dpt values (1, 2, 10);
INSERT 0 1
test=# insert into dpt values (2, 1, 10);
INSERT 0 1
test=# insert into dpt values (2, 1, 10);
INSERT 0 1
test=# insert into dpt values (1, 3, 10);
INSERT 0 1
webarto
06. 09. 2011., 15:56
Pardon, da, samo sabere prvi par ( 1 <=> 2) i iste, ostale, odbaci :)
ivanhoe
06. 09. 2011., 16:24
pih, al ste picajzle... nemam sad vremena, ali videce vi, napravicu JOIN makar crko :P
webarto
06. 09. 2011., 16:33
Ja sam bio pokušao i sa UNION i sa MINUS i na kraju FAIL :D Problem je ovo SUM što "spljošti", ma može se uraditi 100% ali eto :)
razno
06. 09. 2011., 16:48
Mislim da ovo nikako nece uspeti sa JOIN/UNION, bar ne da radi sve.
Inace ovo je bio ispitni zadatak za 5 od 100 poena sa ETF-a
webarto
06. 09. 2011., 17:32
Znači nismo neki 'akeri :D
jablan
06. 09. 2011., 17:39
U principu, može i bez podupita:
select
case when id1 > id2 then id2 else id1 end as a1,
case when id1 > id2 then id1 else id2 end as a2,
sum(broj)
from dpt
group by a1, a2;
Sa JOINOM može eventualno ako povezuješ bukvalno svaki red sam sa sobom da bi swapovao id1 i id2 (onda treba i veštački ključ da se doda), ali to je nepotrebna komplikacija.
ivanhoe
06. 09. 2011., 18:18
@razno: Vidis, moram te baze da polozim vec jednom...
@jablan: da, da, to je dobra ideja...
razno
07. 09. 2011., 02:29
^Ako su baze 1 u pitanju (Bojovic i Milos Cvetanovic), osim ovih par upita koji se pisu (oko 15% ocene) i malo normalizacije (oko 20% ocene) ostalo nisam video da ima veze sa praksom. Uce se i polazu protokoli zakljucavanja,vremenske marke, moguce vrednosti u transakcijama tokom izvrsavanja itd...nesto sto ja u proteklih 8 godina koliko programiram nisam imao potrebu da koristim. Uglavnom je vise teorija kako je implementirana baza, umesto da ima vise prakse :(
Postoji i baze 2 gde se rade NO SQL baze,ali kako sam cuo nije do sada biran zbog kombinacije profesor + asistent.
ivanhoe
07. 09. 2011., 04:22
Ma da, ostale mi te baze, PRS i jos par ispita, vec jedno 5-6 godina...
vBulletin® v3.6.8, Copyright ©2000-2024, Jelsoft Enterprises Ltd.