2012-03-02 5 views
5

Cercherò di rendere la mia domanda più inconfondibile possibile. Mi scuso in anticipo per qualsiasi errore di formulazione mentre cerco di esprimere la mia domanda nel modo migliore possibile:Complemento di un join SQL? È necessario l'aiuto di T-SQL

Utilizzo di T-SQL Ho bisogno di scrivere un'istruzione join che mi ottiene tutti i risultati che hanno una corrispondenza nella tabella A e tabella B

e (!)

un'altra join (o una continuazione della prima aderire) che restituisce tutti i risultati dalla tabella a che non hanno una corrispondenza nella tabella B, ma in questo secondo set di risultati Ho bisogno di avere una delle colonne impostata su "N/A" per identificare i record che non hanno una corrispondenza.

In altre parole, ho bisogno di qualcosa che restituisca tutto nella tabella A, ma identificherebbe anche le righe che non sono state abbinate in B. Tali informazioni vengono quindi utilizzate in un report.

Ecco quello che ho finora:

Ho la prima parte fatta:

LEFT OUTER JOIN dbo.chart B 
ON B.UserName = A.user_name 

Questo mi ottiene i record corrispondenti e solo i record corrispondenti

Ho provato ad aggiungere questa seconda join:

JOIN dbo.chart 
ON NOT EXISTS (select * from B.UserName = A.user_name) 

Sperando che mi ottenga i record non corrispondenti (ero progettando quindi di utilizzare SOSTITUISCI sulla colonna di interesse per etichettare quella colonna "N/A") ma c'è qualcosa di chiaramente sbagliato nel mio sintattico in quanto genera eccezioni.

La mia domanda è cosa devo cambiare per ottenere i risultati necessari. So che ho bisogno di avere almeno un join in quanto ho un'altra parte della query con cui lavorare. Semplicemente non so se ho bisogno di avere che un join restituisca entrambi i set di dati di cui effettivamente ho bisogno di un secondo solo per i record non corrispondenti.

Spero che questo non sia stato troppo confuso. Qualsiasi aiuto sarebbe molto apprezzato.

Grazie!

Aggiornamento: Vorrei solo sottolineare che il motivo per cui ho pensato di utilizzare un secondo join invece di ottenere tutti i risultati in una sola volta è perché ho bisogno di individuare ed etichettare le righe che non sono stati abbinati all'interno di tutto correttamente che Torno.

+0

'join' esterno sinistro dovrebbe darvi quello che volete. Tutte le righe da A e unite a B dove c'è una corrispondenza. Hai una condizione WHERE su alcune colonne nella tabella B? In tal caso, ciò renderebbe il join esterno in un join interno e sarà necessario spostare il segno di spunta nelle colonne della tabella B nella clausola join. –

+0

Grazie per la risposta, Mikael. La cosa più grande che voglio realizzare (e il motivo principale per cui ho preso in considerazione l'idea di utilizzare un secondo join) è quella di essere in grado di identificare e cancellare quali righe sono state abbinate e quali no. – user1179071

+0

Non è necessario un join aggiuntivo per questo. Usa 'Coalesce' come suggerito da Mark in un commento alla risposta di Dems. –

risposta

1

Esempio:

declare @TableA table 
(
    TableAID int, 
    TableAName varchar(10) 
) 

declare @TableB table 
(
    TableBID int, 
    TableBName varchar(10), 
    TableAID int 
) 

insert into @TableA values 
(1, 'A 1'), 
(2, 'A 2'), 
(3, 'A 3') 

insert into @TableB values 
(1, 'B 1', 1), 
(2, 'B 2', 2) 

N/A invece di TableBName:

select A.TableAName, 
     coalesce(B.TableBName, 'N/A') as TableBName 
from @TableA as A 
    left outer join @TableB as B 
    on A.TableAID = B.TableAID 

Risultato:

TableAName TableBName 
---------- ---------- 
A 1  B 1 
A 2  B 2 
A 3  N/A 

colonna supplementare per N/A:

select A.TableAName, 
     B.TableBName, 
     case when B.TableBID is null 
     then 'N/A' 
     else '' 
     end as TableBPresent 
from @TableA as A 
    left outer join @TableB as B 
    on A.TableAID = B.TableAID  

Risultato:

TableAName TableBName TableBPresent 
---------- ---------- ------------- 
A 1  B 1   
A 2  B 2   
A 3  NULL  N/A 
+0

Questo è molto utile. Grazie! – user1179071

+0

Qui è una correzione per renderlo perfetto: 'selezionare A.TableAName, fondono (B.TableBName, 'N ​​/ A') come TableBName da @TableA come A join esterno sinistro selezionare TableID da B su A. TableAID = B.TableAID' – user1179071

+0

@ user1179071 la tua query non è valida –

0

provare a utilizzare un sindacato:

select A.id, b.id, b.desc from tablea A LEFT OUTER JOIN dbo.chart B 
ON B.UserName = A.user_name 

UNION 

select a.id, 0, 'N/A' from tablea where NOT EXISTS (select * from B.UserName = A.user_name) 
+0

È necessario correggere i NON ESISTE. Seleziona * da B dove ... E dovrebbe essere un join interno. – Phil

+0

Grazie. Provando tutto ciò che è stato suggerito. – user1179071

3

Non sono sicuro di dove si sta andando con la seconda join. LEFT JOIN sembra di fare tutto quello che volete ...

DECLARE @tableA TABLE (a_id INT) INSERT INTO @tableA VALUES (1), (2), (3), (4) 
DECLARE @tableB TABLE (b_id INT) INSERT INTO @tableB VALUES  (2), (3) 

SELECT * FROM @tableA AS A LEFT JOIN @tableB AS B on A.a_id = b.b_id 

a_id | b_id 
------+------ 
    1 | NULL 
    2 | 2 
    3 | 3 
    4 | NULL 

A meno che non significa che si sta effettivamente unendo 3 tavoli insieme?Dati

DECLARE @org TABLE (o_io INT) INSERT INTO @org VALUE  (2), (3), (4) 
DECLARE @tableA TABLE (a_id INT) INSERT INTO @tableA VALUES (1), (2), (3), (4) 
DECLARE @tableB TABLE (b_id INT) INSERT INTO @tableB VALUES  (2), (3) 

SELECT 
    * 
FROM 
    @org  AS O 
INNER JOIN 
    @tableA  AS A 
    ON O.o_id = A.a_id 
LEFT JOIN 
    @tableB  AS B 
    ON A.a_id = b.b_id 

o_id | a_id | b_id 
------+------+------ 
    2 | 2 | 2 
    3 | 3 | 3 
    4 | 4 | NULL 
+1

+1 Aggiungi una 'coalizione (B.UserName, 'N ​​/ A')' (o un'altra colonna tabellaB appropriata) alla clausola select per soddisfare il requisito dell'OP per i record "N/A" -segnalati senza record di tabellaB corrispondente. –

+0

Dems, grazie per la vostra risposta. In realtà sono solo due tabelle con cui sto lavorando (dbo.chart e dbo.orgchart sono la stessa cosa). Correggerò il mio tipo nella domanda. – user1179071

+0

Mark, proverò il tuo suggerimento in combinazione con ciò che ha scritto Dems. Grazie! – user1179071