2009-09-03 29 views
19

No es realmente una resta que estoy buscando. Y sé que no es una unión o intersección ... Me han dado un procedimiento almacenado largo y complejo que devuelve una tabla de documentos activos e inactivos. También me han dado un procedimiento almacenado similar que devuelve otra tabla que contiene solo los documentos activos.¿Cómo 'restar' tablas sql?

¿Cómo podría obtener una tabla de documentos inactivos usando estos dos procedimientos de almacenamiento?

Estamos allí utilizando SQL Server 2005.

+0

¿Qué base de datos y cuáles son la (s) tabla (s) y columnas? –

+0

El nombre 'oficial' para este tipo de 'JOIN' es 'LEFT ANTI SEMI JOIN' (al menos esto es lo que SQL Server llama en sus planes de ejecución, y ¿quién soy yo para discutir con una máquina?) Esto se realiza haciendo un bucle sobre todas las filas en un conjunto y descontando aquellas del otro conjunto que coinciden con los criterios especificados. –

Respuesta

33

El funcionamiento de un juego que busca se llama MENOS, pero en SQL Server la palabra clave es EXCEPTO

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

Creo que la operación EXCEPT se convirtió en una disponible en SQL Server 2005.

+1

Esta es la respuesta correcta con respecto a la operación del conjunto subyacente. –

+0

¿Eso existe en el servidor Sql? –

+0

No en el servidor SQL. "Depende" – gbn

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

Suponiendo que estamos identificadores únicos que corresponden en las dos tablas:

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

Creo que EXCEPT es lo que estás buscando. La sintaxis es similar a UNION o INTERSECT.

2

¿Cuál es su motor de DB?

En Oracle, puede usar MINUS configurar el funcionamiento.

En MS SQLServer 2005 y posterior puede usar EXCEPT.

1

En MS TSql, creo que desea la palabra clave EXCEPT.

query1 EXCEPT query2 

Que devolverá todas las filas encontradas en la primera consulta que no se encuentran también en la segunda consulta.

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

esto debería funcionar en casi cualquier motor de base de

+0

He votado esta respuesta porque 'donde Table2.id IS NULL' es exactamente lo que lo hace devolver el inverso. Fue contra intuitivo para mí escribir WHERE Table2.id 'IS NULL' porque ninguna de mis columnas podría ser' NULL' ... ¡pero sí! esa es la magia. Gracias por esto, amigo. – 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

Todas las buenas respuestas, pero falta un punto: El interrogador (OP) ha almacenado procedimientos ...

Tiene que definir tablas temporales (según su plataforma) para cargar los datos

INSERT ... 
EXEC getActive 

INSERT ... 
EXEC getInactive 

Entonces uso, excepto/EXISTE/MENOS/EN/OUTER JOIN/etc ...

+1

¿Qué significa OP? –

+0

Lo siento: "cartel original" – 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' 

Puede probar este tipo de comando para restar una tabla de otra.

0

Para hacer la resta entre tres tablas que he utilizado la siguiente consulta:

Básicamente tienen tres tablas .. Tabla 1, Tabla 2, Tabla 3. En primer lugar he hecho la sustracción de las tablas 1 y 2 y luego hacer la resta entre el resultado de la consulta anterior y la tabla 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

También puede hacer esto con la cláusula NOT IN

Para ejemplo, suponiendo que los procedimientos almacenados he dado las variables de tabla llamados @AllDocuments y @ActiveDocuments y cada documento tiene una columna de identificador de llamada DocId

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

Adapte esto según corresponda para que coincida con los nombres de su tabla/columna.

0

Puede simplemente utilizar la primera sp que devuelve el Active & Inactive y en WHERE coloque la condición para el estado del documento = inactivo, solo obtendrá el documento inactivo.