2009-09-03 19 views
19

Non è proprio una sottrazione che sto cercando. E so che non è un'unione o un'intersezione ... mi è stata data una stored procedure lunga e complessa che restituisce una tabella di documenti attivi e inattivi. Ho anche ricevuto una procedura memorizzata simile che restituisce un'altra tabella che contiene solo i documenti attivi.Come si "sottraggono" le tabelle sql?

Come è possibile ottenere una tabella di documenti inattivi utilizzando queste due procedure di archiviazione?

Stiamo utilizzando SQL Server 2005.

+0

Quale database e quali sono le tabelle e le colonne? –

+0

Il nome 'ufficiale' per questo tipo di 'JOIN' è il' SINISTRA ANTI SEMI JOIN' (almeno questo è ciò che SQL Server chiama nei suoi piani di esecuzione e chi sono io per discutere con una macchina?) Questo viene eseguito eseguendo il ciclo su tutte le righe in un set e attualizzando quelli dell'altro set che corrispondono ai criteri specificati. –

risposta

33

L'operazione set che stai cercando si chiama MINUS, ma in SQL Server la parola chiave è AD ECCEZIONE

SELECT ... // all documents 
    EXCEPT 
    SELECT ... // active documents 

Credo che l'operazione di set EXCEPT è diventato un disponibile in SQL Server 2005.

+1

Questa è la risposta giusta per quanto riguarda l'operazione set sottostante. –

+0

Esiste su Sql Server? –

+0

Non in SQL Server. "Dipende" – gbn

3
select * from MyTable1 
where MyTable1.Field1 not in (
    select Field1 from MyTable2) 
11

solo se ci sono ID univoci che corrispondono tra le due tabelle:

select * from table_both b 
where not exists (select * from table_active a where a.id = b.id) 
3

Credo che EXCEPT sia quello che stai cercando. La sintassi è simile a UNION o INTERSECT.

2

Qual è il tuo motore DB?

In Oracle, è possibile utilizzare l'operazione set MINUS.

In MS SQLServer 2005 e versioni successive è possibile utilizzare EXCEPT.

1

In MS TSql, penso che tu voglia la parola chiave EXCEPT.

query1 EXCEPT query2 

Che restituirà tutte le righe trovate nella prima query che non si trovano anche nella seconda query.

4
SELECT * FROM Table1 
LEFT JOIN Table2 on Table1.id = Table2.id 
WHERE Table2.id IS NULL 

questo dovrebbe funzionare su quasi qualsiasi motore di database

+0

Ho votato questa risposta perché 'where Table2.id IS NULL' è esattamente ciò che fa restituire l'inverso. È stato contro-intuitivo per me scrivere WHERE Table2.id 'IS NULL' perché nessuna delle mie colonne potrebbe essere' NULL' ... ma! questa è la magia. Grazie per questo, amico. – tehprofessor

2
SELECT both.* 
FROM both LEFT OTUER JOIN inactives USING (whatever_id) 
WHERE inactives.whatever_id IS NULL; 

o

SELECT * FROM both 
EXCEPT 
SELECT * FROM inactives; 
8

Tutte le buone risposte, ma manca un punto: L'interrogante (OP) ha memorizzato le procedure ...

È necessario definire tabelle temporanee (basate sulla piattaforma) per caricare i dati

INSERT ... 
EXEC getActive 

INSERT ... 
EXEC getInactive 

Poi uso TRANNE/ESISTE/MENO/IN/outer join/etc ...

+1

cosa significa OP? –

+0

Ci scusiamo: "poster originale" – gbn

0
SELECT roll_number FROM profile WHERE(catagory='Attest and Eat' or catagory='Live and Eat') and status='OK' EXCEPT SELECT roll_number from meal_status WHERE date='29' AND month='1' 

Si può provare questo tipo di comando per sottrarre una tabella da un altro.

0

Per fare la sottrazione tra tre tavoli ho usato la seguente query:

Fondamentalmente ho tre tabelle .. tabella 1, tabella 2, tabella 3. In primo luogo ho fatto la sottrazione della tabella 1 e la tabella 2 e poi fatto la sottrazione tra il frutto di precedente interrogazione e tabella 3.

select v3.Material, ((v1.Qty-v2.Qty)-v3.Qty) as Quantity 
    from table1 v1, table2 v2, table3 v3 
where (v1.Material=v2.Material 
    and v1.Material=v3.Material 
    and v2.Material=v3.Material) 
1

È anche possibile fare questo con la clausola di NOT IN

Per esempio, supponendo che le stored procedure hanno dato le variabili di tabella chiamati @AllDocuments e @ActiveDocuments e ogni documento ha una colonna identificatore denominato DocId

SELECT * FROM @AllDocuments 
WHERE DocId NOT IN 
    (SELECT DocId FROM @ActiveDocuments) 

Adattalo come appropriato per abbinare i nomi della tabella/colonna.

0

si può semplicemente utilizzare il primo sp che restituiscono l'Active & inattivo e in WHERE cluse put condizione per lo stato del documento = inattivo, si wil ottiene solo documento inattivo.

Problemi correlati