Discussione:
Union negativa
(troppo vecchio per rispondere)
Luigi
2006-02-08 16:07:27 UTC
Permalink
Ciao a tutti,
come si fa a fare una Union negativa?
(quello che in Oracle è il minus)

Grazie
Albe V°
2006-02-08 16:15:41 UTC
Permalink
Post by Luigi
Ciao a tutti,
come si fa a fare una Union negativa?
(quello che in Oracle Ú il minus)
Esattamente cosa fa?

Prima Select Minus Seconda Select, estrae tutti i record della prima
che non escono nella seconda?
E quelli che escono nella seconda ma non nella prima, devono apparire?

Se la risposta è no, direi che un normale Left Outer Join con nel Where
un B.ID IS NULL, oppure una subselect con NOT EXISTS.

Ma se fai un esempio capisco meglio...

Ciao

Alberto
--
"Se viriamo, viriamo viriamo viriamo;
Se andiamo dritti, viriamo"
(Cit. "il tattico")
Marcello
2006-02-08 16:39:39 UTC
Permalink
Post by Luigi
Ciao a tutti,
Ciao,
Post by Luigi
come si fa a fare una Union negativa?
(quello che in Oracle è il minus)
In SQL 200 non esiste un operatore diretto. In SQL 2005 è sto introdotto
l'operator except [e intersect] dai un'occhio qui:

http://msdn2.microsoft.com/en-us/library/ms191523.aspx
Post by Luigi
Grazie
marc.
--
marcello poletti
www.epomops.it
http://blogs.dotnethell.it/epomops
Luigi
2006-02-09 08:40:26 UTC
Permalink
Grazie ad entrambi per la risposta.
In realtà era solo una pulce nell'orecchio che mi ha messo un DBA Oracle,
dicendo che da lui esiste questa funzionalità, non presente in SQL Server,
anche se l'utilità di una tale cosa mi sembra piuttosto oscura (se devo
togliere dei dati, tanto vale non estrarli, o no?).
Post by Marcello
Post by Luigi
Ciao a tutti,
Ciao,
Post by Luigi
come si fa a fare una Union negativa?
(quello che in Oracle è il minus)
In SQL 200 non esiste un operatore diretto. In SQL 2005 è sto introdotto
http://msdn2.microsoft.com/en-us/library/ms191523.aspx
Post by Luigi
Grazie
marc.
--
marcello poletti
www.epomops.it
http://blogs.dotnethell.it/epomops
Albe V°
2006-02-09 08:43:21 UTC
Permalink
Post by Luigi
Grazie ad entrambi per la risposta.
In realtà era solo una pulce nell'orecchio che mi ha messo un DBA Oracle,
dicendo che da lui esiste questa funzionalità , non presente in SQL Server,
anche se l'utilità di una tale cosa mi sembra piuttosto oscura (se devo
togliere dei dati, tanto vale non estrarli, o no?).
Si, ma a me interessava sapere cosa fa.

Alberto
--
"Se viriamo, viriamo viriamo viriamo;
Se andiamo dritti, viriamo"
(Cit. "il tattico")
Luigi
2006-02-09 08:49:29 UTC
Permalink
Appunto toglieva dei dati da una serie di Union successive, ma mi sembra un
modo di operare non particolarmente corretto e sensato.
Post by Albe V°
Post by Luigi
Grazie ad entrambi per la risposta.
In realtà era solo una pulce nell'orecchio che mi ha messo un DBA Oracle,
dicendo che da lui esiste questa funzionalità , non presente in SQL Server,
anche se l'utilità di una tale cosa mi sembra piuttosto oscura (se devo
togliere dei dati, tanto vale non estrarli, o no?).
Si, ma a me interessava sapere cosa fa.
Alberto
--
"Se viriamo, viriamo viriamo viriamo;
Se andiamo dritti, viriamo"
(Cit. "il tattico")
Marcello
2006-02-09 09:06:26 UTC
Permalink
Post by Albe V°
Si, ma a me interessava sapere cosa fa.
Ciao Albe,

se non ho capito male il minus di Oracle corrisponde all'except di SQL
2005 quindi:

Select colonne...
tranne
select colonne...
Post by Albe V°
Alberto
marc.
--
marcello poletti
www.epomops.it
http://blogs.dotnethell.it/epomops
Albe V°
2006-02-09 09:11:24 UTC
Permalink
Post by Marcello
Post by Albe V°
Si, ma a me interessava sapere cosa fa.
Ciao Albe,
se non ho capito male il minus di Oracle corrisponde all'except di SQL 2005
Select colonne...
tranne
select colonne...
Basandosi, immagino, su una qualche chiave.
Al che, penso che un Left Outer Join con Is NULL come condizione su un
campo della tabella 'di destra' svolga le stesse funzioni.

Può comunque essere che il Minus sia più leggibile, o più performante,
qualora le due select siano particolarmente complesse...

Ciao

Alberto
--
"Se viriamo, viriamo viriamo viriamo;
Se andiamo dritti, viriamo"
(Cit. "il tattico")
Marcello
2006-02-09 09:17:25 UTC
Permalink
Post by Albe V°
Basandosi, immagino, su una qualche chiave.
Ciao Albe,

no, funziona come la union e la distinct [di cui è fratello stretto]
confrontando i valori coinvolti [quindi la pseudo chiave sono tutti i
valori estratti, osserva questo esempio:

select * from
(select 1 a,2 b
union
select 3 a,4 b
union
select 5 a,6 b)v1
except
select * from
(select 1 a,2 b
union
select 5 a,6 b)v2
Post by Albe V°
Al che, penso che un Left Outer Join con Is NULL come condizione su un
campo della tabella 'di destra' svolga le stesse funzioni.
Sicuramnente si, con il vantaggio che l'assenza di chiavi potrebbe
rendere la clausola on molto complicata.
Post by Albe V°
Può comunque essere che il Minus sia più leggibile, o più performante,
qualora le due select siano particolarmente complesse...
Sicuramente si.
Post by Albe V°
Ciao
Alberto
--
marcello poletti
www.epomops.it
http://blogs.dotnethell.it/epomops
Lorenzo Benaglia
2006-02-09 09:40:16 UTC
Permalink
Post by Albe V°
Basandosi, immagino, su una qualche chiave.
Al che, penso che un Left Outer Join con Is NULL come condizione su un
campo della tabella 'di destra' svolga le stesse funzioni.
Può comunque essere che il Minus sia più leggibile, o più performante,
qualora le due select siano particolarmente complesse...
Ciao Albe,

non conosco il funzionamento dell'operatore minus di Oracle, ma attenzione
che EXCEPT oltre ad aderire allo standard ANSI SQL si comporta diversamente
da una outer join dato che restituisce le righe *distinte* della tabella di
sinistra che non sono presenti in quella di destra (left anti semi join),
quindi sarebbe come una left outer join con la distinct:

USE tempdb;
GO

CREATE TABLE dbo.TableA(
Col1 int
);
GO

CREATE TABLE dbo.TableB(
Col1 int
);
GO

INSERT dbo.TableA VALUES(1);
INSERT dbo.TableA VALUES(2);
INSERT dbo.TableA VALUES(2);
INSERT dbo.TableA VALUES(2);
INSERT dbo.TableA VALUES(3);
INSERT dbo.TableA VALUES(4);
INSERT dbo.TableA VALUES(4);

INSERT dbo.TableB VALUES(1);
INSERT dbo.TableB VALUES(3);
INSERT dbo.TableB VALUES(4);
INSERT dbo.TableB VALUES(4);
GO

/* EXCEPT */
SELECT * FROM dbo.TableA
EXCEPT
SELECT * FROM dbo.TableB;
GO

/* Output:

Col1
-----------
2

(1 row(s) affected)

*/

/* LEFT OUTER JOIN */
SELECT A.*
FROM dbo.TableA AS A
LEFT JOIN dbo.TableB AS B
ON A.Col1 = B.Col1
WHERE B.Col1 IS NULL;
GO

/* Output:

Col1
-----------
2
2
2

(3 row(s) affected)

*/

/* DISTINCT LEFT OUTER JOIN */
SELECT DISTINCT A.*
FROM dbo.TableA AS A
LEFT JOIN dbo.TableB AS B
ON A.Col1 = B.Col1
WHERE B.Col1 IS NULL;
GO

/* Output:

Col1
-----------
2

(1 row(s) affected)

*/

DROP TABLE dbo.TableA, dbo.TableB;

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo
http://italy.mvps.org
Albe V°
2006-02-09 09:55:29 UTC
Permalink
Post by Lorenzo Benaglia
non conosco il funzionamento dell'operatore minus di Oracle, ma attenzione
che EXCEPT oltre ad aderire allo standard ANSI SQL si comporta diversamente
da una outer join dato che restituisce le righe *distinte* della tabella di
sinistra che non sono presenti in quella di destra (left anti semi join),
Si, era chiaro, grazie.

Diciamo che le poche volte che ho avuto bisogno del Union ho in realtà
utilizzato UNION ALL, ma forse anche EXCEPT consente EXCEPT ALL o
analoghi.

Ciao

Alberto
--
"Se viriamo, viriamo viriamo viriamo;
Se andiamo dritti, viriamo"
(Cit. "il tattico")
Lorenzo Benaglia
2006-02-09 10:23:45 UTC
Permalink
Post by Albe V°
Diciamo che le poche volte che ho avuto bisogno del Union ho in realtà
utilizzato UNION ALL, ma forse anche EXCEPT consente EXCEPT ALL o
analoghi.
Ciao Albe,

Da quanto riportato sui BOL, gli operatori EXCEPT ed INTERCEPT non accettano
parametri:

/* EXCEPT */
SELECT * FROM dbo.TableA
EXCEPT ALL
SELECT * FROM dbo.TableB;
GO

/* Output:

Msg 324, Level 15, State 2, Line 3
The 'ALL' version of the EXCEPT operator is not supported.

*/

http://msdn2.microsoft.com/ms188055.aspx

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server

http://blogs.dotnethell.it/lorenzo
http://italy.mvps.org
Albe V°
2006-02-09 10:28:47 UTC
Permalink
Post by Marcello
Post by Albe V°
Diciamo che le poche volte che ho avuto bisogno del Union ho in realtà
utilizzato UNION ALL, ma forse anche EXCEPT consente EXCEPT ALL o
analoghi.
Ciao Albe,
Da quanto riportato sui BOL, gli operatori EXCEPT ed INTERCEPT non accettano
Ah...

In effetti, ragionandoci...

Se accettassero un qualcosa tipo ALL, e nella prima Select uscissero
DUE record uguali, e nalla Select dopo l'EXCEPT uscisse UN record
identico ai due precedenti, quale dovrebbe essere il risultato?
Uno solo (2-1)?
Nessuno?

Occcorrerebbe a questo punto un ulteriore parametro, una sorta di WITH
TIES...

Ok, sto ragionando troppo di accademia...

Ciao

Alberto
--
"Se viriamo, viriamo viriamo viriamo;
Se andiamo dritti, viriamo"
(Cit. "il tattico")
Lorenzo Benaglia
2006-02-09 10:31:05 UTC
Permalink
Post by Albe V°
Ah...
In effetti, ragionandoci...
Se accettassero un qualcosa tipo ALL, e nella prima Select uscissero
DUE record uguali, e nalla Select dopo l'EXCEPT uscisse UN record
identico ai due precedenti, quale dovrebbe essere il risultato?
Uno solo (2-1)?
Nessuno?
Occcorrerebbe a questo punto un ulteriore parametro, una sorta di WITH
TIES...
Ok, sto ragionando troppo di accademia...
:-D
Il tuo ragionamento non fa una piega :-)

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo
http://italy.mvps.org
Lorenzo Benaglia
2006-02-09 10:41:53 UTC
Permalink
Post by Marcello
se non ho capito male il minus di Oracle corrisponde all'except di SQL
Select colonne...
tranne
select colonne...
Ciao Marcello,

"googlando" ho trovato questo PDF:
http://www.dis.uniroma1.it/~derosa/didattica/2005/BasiDati/Cap4.pdf

La slide a pag. 17 riporta:

"Sebbene le operazioni di UNION, INTERSEPT ed EXCEPT sono inclusi nello
standard SQL/92, molti sistemi attualmente supportano solo UNION; inoltre
molti di essi utilizzano lo statement MINUS invece di EXCEPT".

Complimenti per la tua intuizione :-D

ed ancora:

"Nel caso di UNION i duplicati vengono eliminati automaticamente. Per
mantenerli bisogna usare lo statement UNION ALL. Analogamente INTERSECT ALL
e EXCEPT ALL mantengono i duplicati".

Quindi credo che sia una limitazione di SQL Server 2005 il mancato supporto
della clausola ALL per gli operatori INTERSECT e EXCEPT.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo
http://italy.mvps.org
Continua a leggere su narkive:
Loading...