Dati da escludere

lunedì 30 gennaio 2006 - 08.40

lordwaizard Profilo | Senior Member

Ho una query:

SELECT * FROM anagrafica INNER JOIN cb ON (anagrafica.azienda <> cb.azienda)
Questa query funziona perfettamente.

1) Ora vorrei escludere da questo risultato tutte le azienda presente nella tabella fornitori (anagrafica.azienda<>fornitori.nome)
Come posso fare?

(Perchè se la tabella cb non ha nenache un item l'inner non funziona, e se c'è anche solo una riga tutto funziona correttamente?)

2) Una volta ottenuto il risultato dovrebbe prendere la prima riga e fare un INSERT.

Tutto questo è possibile?
Cordiali saluti
3S/Davide Fiorani

lbenaglia Profilo | Guru

> Tutto questo è possibile?

Ciao Davide,

posta un esempio con la struttura semplificata delle tue tabelle (CREATE TABLE...), alcune righe di prova (INSERT INTO...) ed il risultato che vuoi ottenere.

Ciao!

--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

lordwaizard Profilo | Senior Member

TABELLE:
CREATE TABLE [dbo].[anagrafica] (
[id] [int] IDENTITY (1, 1) NOT NULL ,
[azienda] [nvarchar] (50) COLLATE Latin1_General_CI_AS NOT NULL ,
[indirizzo] [nvarchar] (20) COLLATE Latin1_General_CI_AS NULL ,
[paese] [nvarchar] (30) COLLATE Latin1_General_CI_AS NULL ,
[cap] [nvarchar] (10) COLLATE Latin1_General_CI_AS NULL ,
[prov] [nvarchar] (10) COLLATE Latin1_General_CI_AS NULL ,
[stato] [nvarchar] (20) COLLATE Latin1_General_CI_AS NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]


CREATE TABLE [dbo].[fornitori] (
[id] [int] IDENTITY (1, 1) NOT NULL ,
[idm] [int] NOT NULL ,
[nome] [nvarchar] (50) COLLATE Latin1_General_CI_AS NOT NULL ,
[data] [datetime] NULL ,
[nascondi] [nvarchar] (5) COLLATE Latin1_General_CI_AS NULL
) ON [PRIMARY]

CREATE TABLE [dbo].[cb] (
[id] [int] IDENTITY (1, 1) NOT NULL ,
[azienda] [nvarchar] (50) COLLATE Latin1_General_CI_AS NOT NULL ,
[utente] [nvarchar] (50) COLLATE Latin1_General_CI_AS NOT NULL ,
[tipo] [nvarchar] (10) COLLATE Latin1_General_CI_AS NOT NULL ,
[categoria] [nvarchar] (50) COLLATE Latin1_General_CI_AS NOT NULL ,
[data] [datetime] NOT NULL
) ON [PRIMARY]
GO

PROBLEMI
1)
Se eseguo :
SELECT * FROM anagrafica INNER JOIN cb ON (anagrafica.azienda <> cb.azienda)

Non funziona allora ho aggiunto:
INSERT INTO cb(azienda,utente,tipo,categoria,data)VALUES('verdi','davide','tel','A1','12/12/2005')

A questo punto funziona.
perchè?

2)
Desidererei escludere dalla query(SELECT * FROM anagrafica INNER JOIN cb ON (anagrafica.azienda <> cb.azienda) ) tutti i fornitori (presenti nella tabella fornitori.nome)

3) Eseguo la query:
SELECT anagrafica.azienda FROM anagrafica INNER JOIN cb ON (anagrafica.azienda <> cb.azienda)

RISULTATO:
AZIENDA
Verdi
Rossi
Bianchi

E' possibile considerare SOLO il primo record (Verdi) e se esiste un primo record eseguire questa query:
INSERT INTO cb(azienda,utente,tipo,categoria,data)VALUES(AZIENDA,'davide','tel','A1','12/12/2005')
Dove AZIENDA è la voce della prima riga?

Grazie
Davide



lbenaglia Profilo | Guru

>PROBLEMI
>1)
>Se eseguo :
>SELECT * FROM anagrafica INNER JOIN cb ON (anagrafica.azienda
><>cb.azienda)
>
>Non funziona allora ho aggiunto:
>
>A questo punto funziona.
>perchè?

Boh, cosa significa per te "non funziona"?
Ieri ti ho chiesto di postare anche una serie di comandi INSERT INTO per popolare le tabelle con alcune righe di prova e descrivere in modo chiaro quale risultato vuoi ottenere...

Ciao!

--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

lordwaizard Profilo | Senior Member

Scusa per il ritardo della risposta.
Allora l'obbiettivo è semplice devo eseguire una query che mostri tutte leaziende presenti nella tabella anagrafica (anagrafica.azienda) ed escluda tutte le aziende presenti nelle tabelle cd (cb.azienda) e fornitori (fornitori.nome).

1)
non sono capace di escludere due tabelle in contemporanea
Adesso utilizzo
SELECT * FROM anagrafica INNER JOIN cb ON (anagrafica.azienda <> cb.azienda)
escludo le aziende presenti in (cb) ma come faccio ad escludere anche tutte le aziende presenti in fornitori?

2) Non funziona
Se eseguo SELECT * FROM anagrafica INNER JOIN cb ON (anagrafica.azienda <> cb.azienda)
Non ottengo nessun risultato
ma se popolo con
INSERT INTO cb(azienda,utente,tipo,categoria,data)VALUES('verdi','davide','tel','A1','12/12/2005')
Allora mi da tutte le aziende esclusa ovviamente "verdi"
Perchè se una tabella (cb) non è popolata lui non genera una risposta?

3) Se eseguo la query che mi permette di visualizzare tutte le aziende tranne i fornitori e quelle presenti in cb ottengo un risulato.

3a) Come posso selezionare solo la prima riga di questo risulato?
3b) E' possibile verificare sempre tramite query la seguente condizione
SE esiste la prima riga ALLORA INSERISCI il campo AZIENDA in CB

(in modo da scartar quell'azienda in fututro.

Grazie ancora per la disponibilità
Davide



lbenaglia Profilo | Guru

>Scusa per il ritardo della risposta.

Scusami tu Davide,

mi spieghi perché non vuoi postare delle righe di INSERT ed in base a questi dati il result set che vuoi ottenere?
Spesso basta un piccolo esempio per risolvere un "grande" problema :-)

Ciao!

--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

lordwaizard Profilo | Senior Member

L'obbiettivo è quello di mostrare tutte le righe presenti escluse quelle nelle tabelle cb e fornitori.
(L'esclusione avviene confrontando le colonne fornitori.nome, anagrafica.azienda e cb.azienda)
Se l'azienda è presente in fornitori o cb non deve essere visualizzato
Se io nell'esempio scrivo l'insert allora non visualizzo il risultato che mi interessa.
Perchè devrei immettere degli insert nell'esempio se la prima parte è rilevazione e la seconda parte esegue l'insert( e questo l'ho scritto)

Per l'anagrafica mi sono dimenticato, quindi scusa, ma sostazialmente basta considerare una serie di nomi di società presenti nella colonna azienda alcuni presenti in fornitori e cb altri no.
INSERT anagrafica(azienda) VALUES('Verdi')
INSERT anagrafica(azienda) VALUES('Rossi')
INSERT anagrafica(azienda) VALUES('Gialli')



Scusa se sono stato poco chiaro
Grazie
Davide


lbenaglia Profilo | Guru

>Perchè devrei immettere degli insert nell'esempio se la prima
>parte è rilevazione e la seconda parte esegue l'insert( e questo
>l'ho scritto)

Perché se non ci fornisci un esempio completo, dubito che capiremo quello che vuoi fare.
Quindi, o ci fornisci un esempio con tutti i dati richiesti, o temo che purtroppo nessuno ti risponderà.

Ricapitolando, le definizioni delle tabelle le abbiamo, ora ci prepari tanti bei comandi di insert e ci dici quale result set vuoi in output (non a parole, vogliamo le righe!).

Ciao!

--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

lordwaizard Profilo | Senior Member

CREATE TABLE [dbo].[anagrafica] (
[id] [int] IDENTITY (1, 1) NOT NULL ,
[azienda] [nvarchar] (50) COLLATE Latin1_General_CI_AS NOT NULL ,
[indirizzo] [nvarchar] (20) COLLATE Latin1_General_CI_AS NULL ,
[paese] [nvarchar] (30) COLLATE Latin1_General_CI_AS NULL ,
[cap] [nvarchar] (10) COLLATE Latin1_General_CI_AS NULL ,
[prov] [nvarchar] (10) COLLATE Latin1_General_CI_AS NULL ,
[stato] [nvarchar] (20) COLLATE Latin1_General_CI_AS NULL
) ON [PRIMARY]


CREATE TABLE [dbo].[fornitori] (
[id] [int] IDENTITY (1, 1) NOT NULL ,
[idm] [int] NOT NULL ,
[nome] [nvarchar] (50) COLLATE Latin1_General_CI_AS NOT NULL ,
[data] [datetime] NULL ,
[nascondi] [nvarchar] (5) COLLATE Latin1_General_CI_AS NULL
) ON [PRIMARY]

CREATE TABLE [dbo].[cb] (
[id] [int] IDENTITY (1, 1) NOT NULL ,
[azienda] [nvarchar] (50) COLLATE Latin1_General_CI_AS NOT NULL ,
[utente] [nvarchar] (50) COLLATE Latin1_General_CI_AS NOT NULL ,
[tipo] [nvarchar] (10) COLLATE Latin1_General_CI_AS NOT NULL ,
[categoria] [nvarchar] (50) COLLATE Latin1_General_CI_AS NOT NULL ,
[data] [datetime] NOT NULL
) ON [PRIMARY]
GO

INSERT anagrafica(azienda)VALUES('Verdi')
INSERT anagrafica(azienda)VALUES('Gialli')
INSERT anagrafica(azienda)VALUES('Rossi')
INSERT anagrafica(azienda)VALUES('Bianchi')

INSERT fornitori(nome,idm)VALUES('Gialli', 3)




1) Problema
Se io eseguo:
SELECT * FROM anagrafica INNER JOIN cb ON (anagrafica.azienda <> cb.azienda)

Non ottengo nessun risultato.
Se però inserisco anche solo un item nella tabella CB allora funziona correttamente:

INSERT:
INSERT INTO cb(azienda,utente,tipo,categoria,data)VALUES('Verdi','davide','tel','A1','12/12/2005')

OUTPUT di (SELECT anagrafica.azienda FROM anagrafica INNER JOIN cb ON (anagrafica.azienda <> cb.azienda))
Resultset 1
azienda
--------------------------------------------------
Gialli
Rossi
Bianchi

Quindi per fare INNER è obbligatorio che ci sia almeno una riga in entrambe le colonne?


2)
Con SELECT * FROM anagrafica INNER JOIN cb ON (anagrafica.azienda <> cb.azienda) riesco a escludere tutte le aziende presenti

in cb.aziende.
Ora vorrei escludere anche quelle nei fornitori (fornitori.nome)
E' possibile con una sola query escludere sia le aziende presenti CB.azienda che quelle in fornitori.azienda rispetto

anagrafica.azienda?

OUPUT:

Resultset 1
azienda
--------------------------------------------------
Gialli
Bianchi


3A)
OUTPUT:
Resultset 1
azienda
--------------------------------------------------
Gialli
Bianchi

Vorrei considerare solo la prima riga ( Gialli) è possible?



3B)
OUTPUT 1:
Resultset 1
azienda
--------------------------------------------------


OUTPUT 2:
Resultset 1
azienda
--------------------------------------------------
Gialli
Bianchi

Esiste una query che possa verificare se il risultato comprende delle righe (OUTPUT 2) o se non c'è nulla (OUTPUT 1)?

Perchè vorrei fare in modo che nel momento che viene eseguita la query (SELECT * FROM anagrafica INNER JOIN cb ON

(anagrafica.azienda <> cb.azienda)) verifichi il risulato e se esiste (Vedi OUTPUT 2) allora inserisca una riga nella tabella

CB escludendo così l'azienda presente nella prima riga.


INSERT (per l'esclusione):
INSERT INTO cb(azienda,utente,tipo,categoria,data)VALUES(AZIENDA,'davide','tel','A1','12/12/2005')
Dove AZIENDA è la voce della prima riga.


Spero di essermi spiegato meglio, ti ringrazio per la pazienza.
Davide

lbenaglia Profilo | Guru

> Quindi per fare INNER è obbligatorio che ci sia almeno una riga in entrambe le colonne?

Si, una INNER JOIN mette in relazione due tabelle, restituendo le righe comuni in base alle colonne specificate nella clausola ON.

> Ora vorrei escludere anche quelle nei fornitori (fornitori.nome)
> E' possibile con una sola query escludere sia le aziende presenti CB.azienda che quelle in fornitori.azienda rispetto
> anagrafica.azienda?
>
> OUPUT:
>
> Resultset 1
> azienda
> --------------------------------------------------
> Gialli
> Bianchi

Qua non ti seguo.
La tabella [anagrafica] ha le aziende 'Verdi', 'Gialli', 'Rossi' e 'Bianchi', [fornitori] 'Gialli' e [cb] 'Verdi'.
Tu vuoi restituire le aziende non presenti in [fornitori] e [cb], quindi il reult set sarà 'Rossi' e 'Bianchi':

SELECT A.id, A.azienda
FROM dbo.anagrafica AS A
LEFT JOIN dbo.cb
ON A.azienda = cb.azienda
LEFT JOIN dbo.fornitori AS F
ON A.azienda = F.nome
WHERE cb.utente IS NULL
AND F.idm IS NULL
GO

/* Output:

id azienda
----------- --------------------------------------------------
3 Rossi
4 Bianchi

(2 row(s) affected)

*/

Questa query utilizza due LEFT OUTER JOIN per mettere in relazione la tabella [anagrafica] con le altre due e la condizione di WHERE non fa altro che escludere dal result set finale le aziende che non sono presenti nelle tabelle [fornitori] e [cb].

> 3A)
> OUTPUT:
> Resultset 1
> azienda
> --------------------------------------------------
> Gialli
> Bianchi
>
> Vorrei considerare solo la prima riga ( Gialli) è possible?

A parte che il result set è sbagliato, ma in base a quale logica vorresti la prim riga piuttosto che la seconda?

Mi fermo qua perché le altre considerazioni che hai fatto non le ho capite.

Ciao!

--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

lordwaizard Profilo | Senior Member

Ti ringrazio per la soluzione 1 e 2 funziona perfettamente.
Ora per il punto 3.

QUERY:
SELECT A.id, A.azienda
FROM dbo.anagrafica AS A
LEFT JOIN dbo.cb
ON A.azienda = cb.azienda
LEFT JOIN dbo.fornitori AS F
ON A.azienda = F.nome
WHERE cb.utente IS NULL
AND F.idm IS NULL
GO

/* Output:

id azienda
----------- --------------------------------------------------
3 Rossi
4 Bianchi

Il mio obbiettivo è di considerare solo la prima riga (3 rossi) e inserirla il nome della azienda (Rossi) in cb.azienda le altre colonne di cb possono rimanere vuote.

Grazie ancora e scusa per il disturbo
Davide



lbenaglia Profilo | Guru

>Il mio obbiettivo è di considerare solo la prima riga (3 rossi)
>e inserirla il nome della azienda (Rossi) in cb.azienda le altre
> colonne di cb possono rimanere vuote.

E' questo che non capisco, come fai a dire che vuoi Rossi rispettoa Bianchi?
Se il piano di esecuzione della query avesse restituito prima Bianchi andava bene anche lui?!

Insomma, quale criterio utilizzi per dire che Rossi va bene e Bianchi no?

Ciao!

--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

lordwaizard Profilo | Senior Member

L'Ordine lo baserò per anagrafica.id (ORDER BY anagrafica.id ASC)
Però non è assulatamente importante.
Quello che conta è che si esegua la query e che escluda aumaticamente quella azienda (mandandomela in cb).
Quindi la prima che capita va benissimo l'importante che mi inserisca solo 1 azienda in cb (cioè la prima riga) e non tutte le righe ottenute dalla query in questione.

Scusa se son stato poco chiaro.
Davide


lbenaglia Profilo | Guru

>L'Ordine lo baserò per anagrafica.id (ORDER BY anagrafica.id
>ASC)
>Però non è assulatamente importante.
>Quello che conta è che si esegua la query e che escluda aumaticamente
>quella azienda (mandandomela in cb).
>Quindi la prima che capita va benissimo l'importante che mi inserisca
>solo 1 azienda in cb (cioè la prima riga) e non tutte le righe
> ottenute dalla query in questione.

La risposta mi lascia molto perplesso... "la prima che capita va benissimo"....
Boh, a questo punto puoi ricorrere alla funzione di aggregzione MAX() per prendere una sola riga:

SELECT MAX(A.azienda) AS Azienda
FROM dbo.anagrafica AS A
LEFT JOIN dbo.cb
ON A.azienda = cb.azienda
LEFT JOIN dbo.fornitori AS F
ON A.azienda = F.nome
WHERE cb.utente IS NULL
AND F.idm IS NULL
GO

/* Output:

Azienda
--------------------------------------------------
Rossi

(1 row(s) affected)

*/

Ma ripeto, il problema esposto mi lascia molto perplesso...

Ciao!

--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5