[MySQL] roznica zbiorow

0

Witam,

ma ktos moze pod reka zapytanie ktore zwroci roznice zbiorow (tabel), konkretnie A - B ?

  • problem jest taki ze niektore rekordy moga miec pola o takich samych wartosciach!

przyklad:

zbior A sklada sie z elementow {a, b, c, c, c, d, e, f}
zbior B sklada sie z elementow {a, b, c, c, d, e}

wiec A - B = {c, f}

0

nie podales BD, z popularyzatora mysqla wale

create table a1 (v int);
create table a2 (v int);

insert into a1 values(1),(2),(3),(4),(5);
insert into a2 values(6),(7),(3),(4),(5);

-- jakby bylo ladnie ... chyba jeszcze gdzies jest MINUS
select v from a1 EXCEPT select v from a2;

-- a jak nie
select DISTINCT a1.v from (a1 LEFT OUTER JOIN a2 ON a1.v=a2.v) where a2.v IS NULL;
+------+
| v |
+------+
| 1 |
| 2 |
+------+

0

@reichel - oba przypadki nie zadziałają prawidłowo na danych podanych przez cepa :P

0

laaa racja nie dopatrzylem tych ccccc ... no i sie kloci z unikalnosci wierszy troche ...

//--------------------
chcialem wprowadzic numerowanie wierszy (moze da sie latwiej) w zaleznosci od wystapienia i wtedy taki klucz (numer,element zbioru) dalo by juz rade podzielic podana przeze mnie metoda.

Napotkalem jednak blad, czegos nie rozumiem chyba:

mysql> select *, @a, @b, @b=v,
    -> IF (@b IS NULL, "Jest nulem", "Nie jest") AS test,
    -> IF (@b IS NULL, IF((@b:=v) = v,@a:=1,'ZLE'), IF (@b<>v, IF((@b:=v) = v,"@
a:=1", "ZLE1"), @a:=@a+1)) AS WAR
    -> from a2 order by v asc;
+------+------+------+------+------------+------+
| v    | @a   | @b   | @b=v | test       | WAR  |
+------+------+------+------+------------+------+
| 2    | 1    |      | NULL | Jest nulem | 1    |
| 2    | 1    | 2    | 1    | Jest nulem | 1    |
| 3    | 1    | 2    | 0    | Jest nulem | 1    |
| 4    | 1    | 3    | 0    | Jest nulem | 1    |
| 5    | 1    | 4    | 0    | Jest nulem | 1    |
| 6    | 1    | 5    | 0    | Jest nulem | 1    |
| 7    | 1    | 6    | 0    | Jest nulem | 1    |
+------+------+------+------+------------+------+

Na starcie @b jest nulem, potem przybiera wartosci (co widac w kolumnie), mimo to zmienna dalej jest uwazana za nula ?!

0

Ch strasznie nakombinowalem (mam nadzieje ze ktos nakrzyczy !). Nie udalo mi sie rozwiazac problemu null'a tymczasowo zastapilem 'Z'.

Mamy opisany przypadek

insert into a1 values(1),(2),(3),(3),(3),(4),(5),(6);
insert into a2 values(1),(2),(3),(3),(4),(5);

i rozwiazanie

SET @a=1;
SET @b='Z';

SET @c=1;
SET @d='Z';

SET @c1 = 1;
SET @c2 = 1;

SELECT * FROM 

(select v,
@c1:=IF (@c='Z', IF((@c:=a1.v) = a1.v,@d:=1,'ZLE'), IF (@c<>v, IF((@c:=a1.v) = a1.v,@d:=1, "ZLE1"), @d:=@d+1)) AS WAR 
from a1 order by a1.v asc)  AS T2


 LEFT OUTER JOIN 

(select v,
@c2:=IF (@b='Z', IF((@b:=a2.v) = a2.v,@a:=1,'ZLE'), IF (@b<>v, IF((@b:=a2.v) = a2.v,@a:=1, "ZLE1"), @a:=@a+1)) AS WAR 
from a2 order by a2.v asc) AS T1


 ON (T1.v=T2.v) AND (T1.WAR=T2.WAR)

WHERE T1.v IS NULL;

dostajemy

a1-a2
+------+------+------+------+
| v    | WAR  | v    | WAR  |
+------+------+------+------+
| 3    | 3    | NULL |      |
| 6    | 1    | NULL |      |
+------+------+------+------+

znow zalozylem MySQL'a. Nie jest to pelna roznica chcialo by sie FULL OUTER JOINA napisac ale trzeba UNION ....

dodajemy

insert into a2 values(7);

i piszmy z UNION

SET @a=1;
SET @b='Z';

SET @c=1;
SET @d='Z';

SET @c1 = 1;
SET @c2 = 1;

(

SELECT T2.v FROM 

(select v,
@c1:=IF (@c='Z', IF((@c:=a1.v) = a1.v,@d:=1,'ZLE'), IF (@c<>v, IF((@c:=a1.v) = a1.v,@d:=1, "ZLE1"), @d:=@d+1)) AS WAR 
from a1 order by a1.v asc)  AS T2


 LEFT OUTER JOIN 

(select v,
@c2:=IF (@b='Z', IF((@b:=a2.v) = a2.v,@a:=1,'ZLE'), IF (@b<>v, IF((@b:=a2.v) = a2.v,@a:=1, "ZLE1"), @a:=@a+1)) AS WAR 
from a2 order by a2.v asc) AS T1


 ON (T1.v=T2.v) AND (T1.WAR=T2.WAR)

WHERE (T1.v IS NULL) 

)

UNION

(

SELECT T1.v FROM 

(select v,
@c1:=IF (@c='Z', IF((@c:=a1.v) = a1.v,@d:=1,'ZLE'), IF (@c<>v, IF((@c:=a1.v) = a1.v,@d:=1, "ZLE1"), @d:=@d+1)) AS WAR 
from a1 order by a1.v asc)  AS T2


 RIGHT OUTER JOIN 

(select v,
@c2:=IF (@b='Z', IF((@b:=a2.v) = a2.v,@a:=1,'ZLE'), IF (@b<>v, IF((@b:=a2.v) = a2.v,@a:=1, "ZLE1"), @a:=@a+1)) AS WAR 
from a2 order by a2.v asc) AS T1


 ON (T1.v=T2.v) AND (T1.WAR=T2.WAR)

WHERE (T2.v IS NULL) 

);

dostajac

+------+
| v    |
+------+
| 3    |
| 6    |
| 7    |
+------+

niby OK, ale to potwor ....

0

o dzieki za odp, obadam w robocie ;p
tak czy siak moge sobie to rozlozyc na procedury wiec potwor nie potwor :P

niestety w mysql nie domyslili sie ze moze sie cos takiego przydac:

select * from a
minus
select * from b

wrr :/

0

ale uwaga

A DIFFERENCE B <> B DIFFERENCE A

a ostatni kod w to wbija

1 użytkowników online, w tym zalogowanych: 0, gości: 1