[ Orome @ 12.04.2016. 10:53 ] @
imam tabelu kao ovu dole, ono sto mi treba je count(distinct id) samo kod onih 'id' gde je flag nula. znaci ispunjava uslov dok 1 i 2 a ne ispunjava uslov dok 3 i 4. 3 ne ispunjava jer ima jedan red sa 0 i jedan sa 1. 4 ispunjava jer ima samo jedan red sa nulom. znaci treba mi da izbrojim id-jeve tamo gde su svi redovi u tom id-u nula. ne brojim redove nego cele id-jeve.

rj - id - flag
1 - 1 - 0
1 - 1 - 0
1 - 2 - 0
1 - 3 - 0
1 - 3 - 1
1 - 4 - 1
2 - 1 - 0
[ dusans @ 12.04.2016. 10:59 ] @
Citat:

... 4 ispunjava jer ima samo jedan red sa nulom

Ja vidim da 4 ima jedan red sa jedinicom a ne nulom.

U principu je sve jasno ali ne i rezultat, napiši primer izlaza za ove podatke...
[ Orome @ 12.04.2016. 11:12 ] @
izvini, to je greska. 4 je trebala biti sa nulom. medjutim posto je sa jedinicom rezultat je sledeci :

rj - count_id
1 - 2 (id 1 i 2)
2 - 1 (id 1)
[ dusans @ 12.04.2016. 11:22 ] @
Evo ti rešenja u T-SQLu pošto ne radim MySql:
Code (sql):

SELECT rj, COUNT(id) AS count_id
FROM
(
     SELECT rj, id,
             SUM(CASE WHEN flag = 0 THEN 1 ELSE 0 END) AS C0,
             SUM(CASE WHEN flag = 0 THEN 0 ELSE 1 END) AS CX
     FROM rec GROUP BY rj, id
) AS main
WHERE (C0 > 0) AND (CX = 0)
GROUP BY rj
 


U MySql-u umesto CASE koristi IF, ne znam sintaksu, nešto tipa:
Code (sql):

SUM(IF(flag = 0, 1, 0)) AS C0,
SUM(IF(flag = 0, 0, 1)) AS CX
 
[ djoka_l @ 12.04.2016. 11:27 ] @
sledeći upit izbacuje id za koji ne postoji ni jedan red sa flagom različitim od nule

Code (sql):

SELECT DISTINCT id
FROM ttt a
WHERE NOT EXISTS (
   SELECT b.id
   FROM ttt b
   WHERE b.id = a.id
   AND flag != 0)
 


a ovaj njihov broj

Code (sql):

SELECT COUNT(*)
FROM (
  SELECT DISTINCT id
  FROM ttt a
  WHERE NOT EXISTS (
     SELECT b.id
     FROM ttt b
     WHERE b.id = a.id
     AND flag != 0)
)
 


Prvi upit radi dobro ako postoji indeks nad id. Ako ne postoji, onda sledeći upit može da radi brže:
Code (sql):

SELECT DISTINCT id
FROM ttt a
WHERE a.id NOT IN (
   SELECT DISTINCT b.id
   FROM ttt b
   WHERE flag != 0)
 



[Ovu poruku je menjao djoka_l dana 12.04.2016. u 12:37 GMT+1]
[ bogdan.kecman @ 12.04.2016. 11:42 ] @
Code (sql):


mysql> CREATE TABLE t1 ( rj INT,  id INT, flag INT)engine=myisam;
Query OK, 0 ROWS affected (0.01 sec)

mysql> INSERT INTO t1 VALUES (1,1,0), (1,1,0), (1,2,0), (1,3,0), (1,3,1), (1,4,1), (2,1,0);
Query OK, 7 ROWS affected (0.02 sec)
Records: 7  Duplicates: 0  Warnings: 0

mysql> SELECT MAX(rj), id, COUNT(*) FROM t1 GROUP BY id HAVING SUM(flag) = 0;
+---------+------+----------+
| MAX(rj) | id   | COUNT(*) |
+---------+------+----------+
|       2 |    1 |        3 |
|       1 |    2 |        1 |
+---------+------+----------+
2 ROWS IN SET (0.00 sec)

 


[ djoka_l @ 12.04.2016. 11:44 ] @
A može i kako je bogdan napisao

Radi ako nema negativnih vrednosti u polju flag
[ dusans @ 12.04.2016. 11:44 ] @
Code (sql):

SELECT rj, COUNT(id) AS count_id
FROM
(
     SELECT rj, id FROM rec
     GROUP BY rj, id HAVING SUM(flag) = 0
) AS main GROUP BY rj
 
[ dusans @ 12.04.2016. 11:52 ] @
Bogdane, šta propuštam sa ovim MAX(rj), nije mi jasan?
[ bogdan.kecman @ 12.04.2016. 12:09 ] @
malo je nejasno covek napisao sta hoce pa ja sad nagadjam sta mu je cilj, ono kako je napisao to mu dodje taj moj upit eventualno umesto HAVING SUM(flag) = 0; da stavi HAVING SUM(ABS(flag)) = 0; ako ima i negativne vrednosti da upit uvek bude validan ..

MAX(rj) je zbog SQL standarda, ne mozes da imas u select spisku vrednost koja nije jednoznacna, posto u tom upitu imas GROUP BY id to znaci da jedino ID ima jednoznacnu vrednost i naravno rezultati agregacionih funkcija ali RJ ne moze da bude jednoznacan, to sto u njegovom slucaju jeste je zato sto je tako ubacio datu ali mogao je da upise datu i drugacije ... primer, da je umesto

(1,1,0), (1,1,0), (1,2,0), (1,3,0), (1,3,1), (1,4,1), (2,1,0);

imao

(5,1,0), (1,1,0), (1,2,0), (1,3,0), (1,3,1), (1,4,1), (2,1,0);

koji RJ u tom slucaju treba da mu vratis za id 1? 5 ili 1, stare verzije mysql-a ne postuju standard po tom pitanju i vratice ti nekad 5 nekad 1 (nikad ne znas koji) ali nece prijaviti gresku, novi mysql po defaultu vraca gresku da je upit nevalidan ... te posto je njemu ocigledno svejedno koji RJ ce da vrati ja sam stavio MAX() da bi imao validan upit, moze da bude i min i avg i sta god vec mu treba .... dodatno sto mysql ne podrzava windowed funkcije ali da ne idemo sad na tu stranu....

e sad, sve to ako sam ja skontao sta je orome hteo posto mu simplifikacija problema nije bila bas 100% uspesna :D nadam se da ce uspeti da iskoristi odgovore, ako ne, morace da da malo tacniji opis problema da bi dobio i tacniji odgovor
[ jablan @ 12.04.2016. 12:17 ] @
Code:

mysql> select a.rj, count(distinct a.id) from  tabela as a
       left join tabela as b on a.id = b.id and b.flag <> 0
       where b.id is null
       group by a.rj;
+------+----------------------+
| rj   | count(distinct a.id) |
+------+----------------------+
|    1 |                    2 |
|    2 |                    1 |
+------+----------------------+
2 rows in set (0.01 sec)


BTW ne savetujem vam da se oslanjate na hakove sa SUM().

//edit: indent

[Ovu poruku je menjao jablan dana 12.04.2016. u 13:30 GMT+1]
[ dusans @ 12.04.2016. 12:19 ] @
Objasnio je output u trećem post-u, rezultati su grupisani po rj.
http://www.elitesecurity.org/t490232-0#3668729
Code:

rj - count_id
1 - 2 (id 1 i 2)
2 - 1 (id 1) 


Kopka me da li takav output može da se dobije prostije od ovoga:
http://www.elitesecurity.org/t490232-0#3668747
Code (sql):

SELECT rj, COUNT(id) AS count_id
FROM
(
     SELECT rj, id FROM rec
     GROUP BY rj, id HAVING SUM(flag) = 0
) AS main GROUP BY rj
 
[ bogdan.kecman @ 12.04.2016. 12:26 ] @
al ga je objasio bas je sve jasno ?!?!?!

izvini, to je greska. 4 je trebala biti sa nulom. medjutim posto je sa jedinicom rezultat je sledeci :

rj - count_id
1 - 2 (id 1 i 2)
2 - 1 (id 1)


sta je "2 (id 1 i 2)" - koji je to "rezultat" ..
po cemu je RJ unique vezan za ID ? sta ako je data

(5,1,0), (1,1,0), (1,2,0), (1,3,0), (1,3,1), (1,4,1), (2,1,0)

kako onda treba da izgleda izlaz?

posto to sto on ima 1:1 unutar tabele izmedju RJ i ID jel to pravilo ili? cemu onda sluzi ID ako je RJ u 1:1 sa ID ?

tvoj upit ce da vrati

Code:

mysql> SELECT rj, COUNT(id) AS count_id
    -> FROM
    -> (
    ->      SELECT rj, id FROM t1 GROUP BY rj, id HAVING SUM(flag) = 0
    -> ) AS main GROUP BY rj
    ->  ;
+------+----------+
| rj   | count_id |
+------+----------+
|    1 |        2 |
|    2 |        1 |
|    5 |        1 |
+------+----------+


jel to hteo?
[ bogdan.kecman @ 12.04.2016. 12:38 ] @
(btw sad citam ovaj moj post deluje kao da se svadjam - ne svadjam se!!! nego mi i dalje nije jasno sta mu je zahtev)
[ dusans @ 12.04.2016. 12:47 ] @
Da definitivno je hteo takav output.
Jedino gde mi još uvek nije jasan koji je scope u kom gleda da li su svi flagovi nula za neki id.
Da li je taj scope cela tabela ili samo u okviru posmatrane rj.
Napisao je kao da je u pitanju cela tabela ali ne mora da znači pošto je bio dosta nedorečen u prvom postu.
[ bogdan.kecman @ 12.04.2016. 12:51 ] @
sta znam, ja nikako ne vidim iz njegovih postova sta je hteo :D najmanje
da je hteo ovaj zadnji output no mozda bolje da sacekamo njega :D
[ Orome @ 12.04.2016. 13:24 ] @
evo me, dusans je shvatio i dao resenje

Code:

SELECT rj, COUNT(id) AS count_id
FROM
(
     SELECT rj, id,
             SUM(CASE WHEN flag = 0 THEN 1 ELSE 0 END) AS C0,
             SUM(CASE WHEN flag = 0 THEN 0 ELSE 1 END) AS CX
     FROM rec GROUP BY rj, id
) AS main
WHERE (C0 > 0) AND (CX = 0)
GROUP BY rj


hvala na svim odgovorima. sto se tice drugih, djoka_l ne radi ovaj upit.

@bogdan ne znam sta nije jasno, sto se tice ovog dela

rj - count_id
1 - 2 (id 1 i 2)
2 - 1 (id 1)

pod rj 1 ocekivani rezultat je 2 a u zagradi je objasnjenje po id koji id-jevi ispunjavaju uslov. imao sam samo jos da dodam tacan where uslov koji ce proraditi. rj je podatak koji se nalazi u bazi i po hijerarhiji je na vrhu ovog seta. u okviru rj mi treba broj id-jeva koji ispunjavaju uslov.

izvinjavam se zbog nedorecenosti.
[ dusans @ 12.04.2016. 13:28 ] @
id ispunjava uslov ako su sve njegove pojave sa flag=0.
Pošto je nedorečeno, pojasni - da li si mislio na pojave u celoj tabeli ili samo na pojave u posmatranoj rj?
[ djoka_l @ 12.04.2016. 13:29 ] @
Pa, ja sam odgovorio na tvoj prvi post
Citat:
imam tabelu kao ovu dole, ono sto mi treba je count(distinct id) samo kod onih 'id' gde je flag nula. znaci ispunjava uslov dok 1 i 2 a ne ispunjava uslov dok 3 i 4. 3 ne ispunjava jer ima jedan red sa 0 i jedan sa 1. 4 ispunjava jer ima samo jedan red sa nulom. znaci treba mi da izbrojim id-jeve tamo gde su svi redovi u tom id-u nula. ne brojim redove nego cele id-jeve.


A imao sam problema da shvatim, recimo "znaci ispunjava uslov dok 1 i 2"
[ bogdan.kecman @ 12.04.2016. 13:41 ] @
Citat:
Orome:
@bogdan ne znam sta nije jasno



kako nije nejasno :D da si im bar dao neka imena koja imaju smisla :D nije mi jasno kako je samo dusan uspeo da zakljuci iz ovako sturih podataka sta ti treba :D

elem u svakom slucaju ovaj dusanov groupby(groupby) ti dodje to resenje koje najlakse radi verovatno ceo sistem moze drugacije da se optimizuje ali ne sa ovoliko podataka :D
[ dusans @ 12.04.2016. 13:48 ] @
Jablan je dao genijalno rešenje, super dosetka.
Mada može da bude problema sa performansama ako ima puno ne-0 podataka
pošto se radi o "skoro" dekartovom proizvodu po id-u kod join-a.
[ bogdan.kecman @ 12.04.2016. 14:05 ] @
yup, odlicno resenje, ne znam kako sam ga preskocio

@jablan, ja sam pretpostavio iz njegovog zahteva da mu je rj "nebitan podatak" te da mu bilo koji iz grupe radi posao a da hoce da grupise po ID i da mu je id bitan podatak te max() tu znaci "daj bilo koji" a on u stvari oce group by rj i count .. skroz druga prica
[ jablan @ 12.04.2016. 16:35 ] @
Citat:
dusans:
Jablan je dao genijalno rešenje, super dosetka.
Mada može da bude problema sa performansama ako ima puno ne-0 podataka
pošto se radi o "skoro" dekartovom proizvodu po id-u kod join-a.

Nije u pitanju dosetka, ovo (self LEFT OUTER JOIN + IS NULL uslov) je klasičan pristup u mnogo situacija (npr traženje lokalnog maksimuma itd)... I tačno je da je sporije (makar na mysql-u), probao sam sa oko milion redova.

Inače, u vašem pristupu (subquery) bih umesto SUM() koristio npr BIT_OR() agregatnu funkciju, mislim da ima više smisla za flagove, a i ne pravi problem sa negativnim vrednostima.
[ bogdan.kecman @ 12.04.2016. 17:41 ] @
da, left outer self join pomaze kod mysql-ovih nedostataka u odnosu na
sql standard .. nije ubitacno brzo ali radi posao .. mada evo placem na
prava vrata vec dugo vreme mozda bude uskoro :D
[ Orome @ 13.04.2016. 08:41 ] @
Citat:
dusans:
id ispunjava uslov ako su sve njegove pojave sa flag=0.
Pošto je nedorečeno, pojasni - da li si mislio na pojave u celoj tabeli ili samo na pojave u posmatranoj rj?


u celoj tabeli grupisano po rj.
[ anon115774 @ 13.04.2016. 10:40 ] @
Ja koliko sam razumeo covek hoce ovo:

Code:
select count(distinct id) from t1 where flag = 0
[ dusans @ 13.04.2016. 11:09 ] @
On je hteo da izbroji koliko različitih ID-eva koji "ispunjavaju uslov" ima po svakoj rj.
ID "ispunjava uslov" kada sve njegove pojave u okviru posmatrane rj imaju flag=0.

Code:

Input:
rj   id   flag
1    1    0
1    1    0
1    2    0
1    3    0
1    3    1
1    4    1
2    1    0
2    2    0
2    2    1
2    4    0
2    5    0
3    3    0

Output:
rj   id_count
1    2
2    3
3    1



[Ovu poruku je menjao dusans dana 13.04.2016. u 12:22 GMT+1]
[ anon115774 @ 13.04.2016. 11:26 ] @
E onda sam ja totalno promasio sta je on hteo ili on nije objasnio dobro :)