|
|
Subject: Grave problema utilizzando UNION ALL
From: Andrea Morelli
Date: 5/4/2007 10:28:10 AM
Salve a tutto il NG!
Ho un problema abbastanza grave e non riesco proprio a risolverlo.
Ho due tabelle praticamente identiche, la prima WORK, l'altra LAB, dove ogni
mese i dati della WORK si trasferiscono nella LAB attraverso job creati da
me.
Ora dovrei popolare una vista con i dati di queste WORK e LAB che vanno in
JOIN con una mia terza tabella.
La tabella si chiama RIEPILOGO, ha come chiave il campo ID che fa
riferimento alla chiave IDWORK e IDLAB.
Io eseguo la seguente query:
SELECT * FROM Riepilogo r LEFT JOIN
Work w ON r.ID = w.IDWORK
UNION ALL
SELECT * FROM Riepilogo r LEFT JOIN
Lab l ON r.ID = l.IDLAB
e nonostante io abbia gli ID di RIEPILOGO nella sola tabella WORK,
giustamente mi raddoppia le righe perchè effettuo una LEFT anche sulla
tabella LAB.
Premesso che questa LEFT devo per forza di cose averla, come faccio a dire
alla mia query: tornami soltanto i dati della tabella in cui sono presenti i
miei ID della tabella RIEPILOGO?
Spero qualcuno possa aiutarmi. Grazie in anticipo.
Ciao.
Subject: Grave problema utilizzando UNION ALL
From: Lorenzo Benaglia
Date: 5/4/2007 11:06:36 AM
Andrea Morelli wrote:
> Io eseguo la seguente query:
>
> SELECT * FROM Riepilogo r LEFT JOIN
> Work w ON r.ID = w.IDWORK
> UNION ALL
> SELECT * FROM Riepilogo r LEFT JOIN
> Lab l ON r.ID = l.IDLAB
>
> e nonostante io abbia gli ID di RIEPILOGO nella sola tabella WORK,
> giustamente mi raddoppia le righe perchè effettuo una LEFT anche sulla
> tabella LAB.
>
> Premesso che questa LEFT devo per forza di cose averla, come faccio a
> dire alla mia query: tornami soltanto i dati della tabella in cui
> sono presenti i miei ID della tabella RIEPILOGO?
Ciao Andrea,
Sarebbe buona norma fornire un esempio completo (CREATE TABLE, INSERT e
result set desiderato) in modo da agevolare la vita a chi cerca di
interpretare la situazione.
Anch'io come Alberto non ho le idee chiare, ma probabilmente potresti fare
una cosa del genere:
WITH CTE_Dati(Id, col2,..., coln) AS
(
SELECT IDWORK, col2,..., coln
FROM dbo.Work
UNION ALL
SELECT IDLAB, col2,..., coln
FROM dbo.Lab
)
SELECT *
FROM dbo.Riepilogo AS R
LEFT JOIN CTE_Dati AS CTE
ON R.ID = CTE.Id;
Se utilizzi SQL Server 2000 trasforma la CTE in una tabella derivata.
> Grazie in anticipo.
Prego.
Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo
http://italy.mvps.org
Subject: Grave problema utilizzando UNION ALL
From: Andrea Morelli
Date: 5/4/2007 11:11:34 AM
Albe V° wrote:
> Andrea Morelli ha pensato forte :
>> Salve a tutto il NG!
>> Ho un problema abbastanza grave e non riesco proprio a risolverlo.
>>
>> Ho due tabelle praticamente identiche, la prima WORK, l'altra LAB, dove
>> ogni
>> mese i dati della WORK si trasferiscono nella LAB attraverso job creati
>> da
>> me.
>>
>> Ora dovrei popolare una vista con i dati di queste WORK e LAB che vanno
>> in
>> JOIN con una mia terza tabella.
>>
>> La tabella si chiama RIEPILOGO, ha come chiave il campo ID che fa
>> riferimento
>> alla chiave IDWORK e IDLAB.
>>
>> Io eseguo la seguente query:
>>
>> SELECT * FROM Riepilogo r LEFT JOIN
>> Work w ON r.ID = w.IDWORK
>> UNION ALL
>> SELECT * FROM Riepilogo r LEFT JOIN
>> Lab l ON r.ID = l.IDLAB
>>
>> e nonostante io abbia gli ID di RIEPILOGO nella sola tabella WORK,
>> giustamente mi raddoppia le righe perchè effettuo una LEFT anche sulla
>> tabella LAB.
>>
>> Premesso che questa LEFT devo per forza di cose averla, come faccio a
>> dire
>> alla mia query: tornami soltanto i dati della tabella in cui sono
>> presenti i
>> miei ID della tabella RIEPILOGO?
>
> Forse non ho capito: tu vorresti un risultato da INNER JOIN utilizzando
> però un LEFT OUTER JOIN?
>
> Se così fosse, basterebbe cambiare LEFT con INNER, ma immagino di avere
> frainteso...
>
> Alberto
Nella mia tabella di Riepilogo ho dei dati che, se metto in inner join con
la WORK e con la LAB, li perdo, perciò devo per forza utilizzare una LEFT.
Solo che essendo una union i dati restituiti (ovviamante) si raddoppiano,
mentre invece vorrei che mi restituisse solo quelli in cui realmente
esistono.
Subject: Grave problema utilizzando UNION ALL
From: AlessandroD
Date: 5/4/2007 11:21:28 AM
Andrea Morelli wrote:
>
> Io eseguo la seguente query:
>
> SELECT * FROM Riepilogo r LEFT JOIN
> Work w ON r.ID = w.IDWORK
> UNION ALL
> SELECT * FROM Riepilogo r LEFT JOIN
> Lab l ON r.ID = l.IDLAB
>
> e nonostante io abbia gli ID di RIEPILOGO nella sola tabella WORK,
>
Non capisco, se gli ID di Riepilogo dici che vengono usati solo nella
tabelle Work, che senso ha fare una select di union? Per come hai scritto,
io ho capito che gli ID di Lab non sono mai in comune con quelli di
Riepilogo quindi che senso ha la seconda select?
> giustamente mi raddoppia le righe perchè effettuo una LEFT anche sulla
> tabella LAB.
>
E, appunto.
> Premesso che questa LEFT devo per forza di cose averla, come faccio a
> dire alla mia query: tornami soltanto i dati della tabella in cui
> sono presenti i miei ID della tabella RIEPILOGO?
>
Non mi è proprio chiaro che ti serve e la natura del problema, ad ogni modo
per legare tutta la Riepilogo alla somma di Work e Lab puoi procedere in
questo modo:
select *
from
Riepilogo r left join (
select * from Work
union
select * from Lab
) t
on r.ID= t.IDWork
Il join è fatto su IDWork visto che il nome dei campi della subselect t
deriva dalla prima tabella usata nella union che per l'appunto è la Work.
Se questo no ti va bene posta la struttura delle tabelle, dei dati di
esempio e il risultato che ti serve, altrimenti è difficile che si riesca ad
essere di aiuto.
Ciao, Alessandro
Subject: Grave problema utilizzando UNION ALL
From: Andrea Morelli
Date: 5/4/2007 11:27:45 AM
Lorenzo Benaglia wrote:
> Sarebbe buona norma fornire un esempio completo (CREATE TABLE, INSERT e
> result set desiderato) in modo da agevolare la vita a chi cerca di
> interpretare la situazione.
Hai ragione scusa, faccio un esempio per essere il + chiaro possibile.
Naturalmente mostro soltanto una minima serie di informazioni perchè le
tabelle sono abbastanza grandi.
TABELLA RIEPILOGO
- ID int
es.(1,2,3,4,5,6,7,8)
TABELLA WORK
-IDWORK int
es.(non ci sono dati)
TABELLA LAB
- IDLAB
es. (1,2,3,4,5,6)
La mia query:
> SELECT * FROM Riepilogo r LEFT JOIN
> Work w ON r.ID = w.IDWORK
> UNION ALL
> SELECT * FROM Riepilogo r LEFT JOIN
> Lab l ON r.ID = l.IDLAB
restituisce
|ID|
1, della tab.work
2, della tab.work
3, della tab.work
4, della tab.work
5, della tab.work
6, della tab.work
7, della tab.work
8, della tab.work
1, della tab.lab
2, della tab.lab
3, della tab.lab
4, della tab.lab
5, della tab.lab
6, della tab.lab
7, della tab.lab
8 della tab.lab
mentre io vorrei che mi restituisse soltanto i dati della tab.lab dove
effettivamente vanno in join con la mia tabella di riepilogo. Lo so che è
complicata come situazione perchè sono io a volere la left ma intanto se
faccio l'inner i dati 7,8 non mi vengono restituiti.
Uso SQL2000. Come si crea una tabella derivata?
Subject: Grave problema utilizzando UNION ALL
From: Lorenzo Benaglia
Date: 5/4/2007 11:44:32 AM
Andrea Morelli wrote:
> Hai ragione scusa, faccio un esempio per essere il + chiaro possibile.
> Naturalmente mostro soltanto una minima serie di informazioni perchè
> le tabelle sono abbastanza grandi.
>
> TABELLA RIEPILOGO
> - ID int
> es.(1,2,3,4,5,6,7,8)
Io ti avrei chiesto I COMANDI SQL....
> Uso SQL2000. Come si crea una tabella derivata?
Così:
USE tempdb;
CREATE TABLE dbo.Riepilogo(
id int NOT NULL PRIMARY KEY
);
CREATE TABLE dbo.Work(
idwork int NOT NULL PRIMARY KEY
);
CREATE TABLE dbo.Lab(
idlab int NOT NULL PRIMARY KEY
);
INSERT dbo.Riepilogo VALUES(1);
INSERT dbo.Riepilogo VALUES(2);
INSERT dbo.Riepilogo VALUES(3);
INSERT dbo.Riepilogo VALUES(4);
INSERT dbo.Riepilogo VALUES(5);
INSERT dbo.Riepilogo VALUES(6);
INSERT dbo.Riepilogo VALUES(7);
INSERT dbo.Riepilogo VALUES(8);
INSERT dbo.Lab VALUES(1);
INSERT dbo.Lab VALUES(2);
INSERT dbo.Lab VALUES(3);
INSERT dbo.Lab VALUES(4);
INSERT dbo.Lab VALUES(5);
INSERT dbo.Lab VALUES(6);
SELECT *
FROM dbo.Riepilogo AS R
LEFT JOIN (
SELECT idwork AS id
FROM dbo.Work
UNION ALL
SELECT idlab
FROM dbo.Lab
) AS Q
ON R.id = Q.id;
/* Output:
id id
----------- -----------
1 1
2 2
3 3
4 4
5 5
6 6
7 NULL
8 NULL
(8 row(s) affected)
*/
DROP TABLE dbo.Riepilogo, dbo.Work, dbo.Lab;
Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo
http://italy.mvps.org
Subject: Grave problema utilizzando UNION ALL
From: Andrea Morelli
Date: 5/4/2007 12:04:39 PM
Albe V° wrote:
> Il 04/05/2007, Andrea Morelli ha detto :
>> Nella mia tabella di Riepilogo ho dei dati che, se metto in inner join
>> con la
>> WORK e con la LAB, li perdo, perciò devo per forza utilizzare una LEFT.
>> Solo
>> che essendo una union i dati restituiti (ovviamante) si raddoppiano,
>> mentre
>> invece vorrei che mi restituisse solo quelli in cui realmente esistono.
>
> Continuo a non capire.
>
> Se i dati di Work periodicamente vengono spostati in Lab, direi che
> l'ID viene mantenuto, quindi gli ID di Work e di Lab sono sempre
> diversi e non ci sono 'doppioni'.
> Quindi, perchè le righe vengono raddoppiate?
>
> Ciao
>
> Alberto
Mi raddoppia tutto perchè faccio una LEFT in entrambe le tabelle... Quindi
anche se non ci sono i dati in una delle due tabella la LEFT me le
restituisce lo stesso. Cmq ho risolto, grazie mille per l'aiuto.
Subject: Grave problema utilizzando UNION ALL
From: Andrea Morelli
Date: 5/4/2007 12:03:00 PM
Lorenzo Benaglia wrote:
> Io ti avrei chiesto I COMANDI SQL....
Ah scusa non avevo capito :\
> SELECT *
> FROM dbo.Riepilogo AS R
> LEFT JOIN (
> SELECT idwork AS id
> FROM dbo.Work
>
> UNION ALL
>
> SELECT idlab
> FROM dbo.Lab
> ) AS Q
> ON R.id = Q.id;
>
Magnifico. Non so come ho fatto a non pensarci. E' esattamente ciò che
volevo.
Grazie mille sia a te che ad AlessandroD che mi avete risposto in egual
modo.
>
> Ciao!
Ciao e grazie ancora!
|