2010-10-12 11 views
5

Actualmente luchando por encontrar una manera de validar 2 tablas (eficientemente una gran cantidad de filas de la tabla A)de consultas SQL - Asegúrese de que exista una fila para cada valor de()

tengo dos tablas

Tabla A

ID 
A 
B 
C 

Tabla emparejados

ID Number 
A 1 
A 2 
A 9 
B 1 
B 9 
C 2 

Estoy tratando de escribir una consulta SQL Server que básicamente comprueba para asegurarse de que para cada valor en la tabla A existe una fila para un conjunto variable de valores (1, 2,9)

El ejemplo anterior es incorrecto porque t debería tener para cada registro en A un registro correspondiente en la Tabla emparejada para cada valor (1,2,9). El objetivo final es:

Tabla igualada

ID Number 
A 1 
A 2 
A 9 
B 1 
B 2 
B 9 
C 1 
C 2 
C 9 

Sé que es confuso, pero en general, para toda x en (un conjunto) no debe haber un registro correspondiente en la tabla igualada. Obviamente he simplificado las cosas.

Háganme saber si todos necesitan una aclaración.

+0

¿Siempre hay tres valores? ¿Los valores son siempre 1,2 y 9? – Kuberchaun

+1

No, en realidad hay 17 valores ... y no son secuenciales. (1,3,4,5 7, etc.) – Nix

Respuesta

10

Uso:

SELECT a.id 
    FROM TABLE_A a 
    JOIN TABLE_B b ON b.id = a.id 
    WHERE b.number IN (1, 2, 9) 
GROUP BY a.id 
    HAVING COUNT(DISTINCT b.number) = 3 

El DISTINCT en el COUNT asegura que los duplicados (IE: A que tiene dos registros en TABLE_B con el valor "2") de ser considerado falsamente un registro correcto. Se puede omitir si la columna number tiene una restricción de clave única o primaria.

El HAVING COUNT(...)obligada igual al número de valores proporcionados en la cláusula de IN.

+0

Creo que esto funcionará, estúpido simple (frustrante). Probando ahora. Gracias. – Nix

+0

@Nix: ¿Supongo que podría hacerlo más enrevesado? :) –

+0

1: se ve bien ... – RedFilter

0

Cree una tabla de valores temporales que desee. Puede hacerlo de forma dinámica si los valores 1, 2 y 9 están en alguna tabla desde la que puede realizar consultas.

Entonces, SELECT FROM tempTable WHERE NOT IN (SELECT * FROM TableMatched)

+0

necesito para asegurarse de que para cada fila existen todos los valores de EN en la tabla de partido. ¿Eso solo me dirá si tengo valores que no están ahí? – Nix

+0

¿Qué desea que suceda si faltan registros? Mi SELECT no devolverá ningún registro si todos los registros deseados existen en TableMatched. Eso sería pasar la prueba, ¿verdad? Si hay registros devueltos aquí, la prueba falla. ¿Desea que este SQL INSERTE los registros faltantes? – DOK

0

tuve esta situación una vez. Mi solución fue la siguiente.

Además de TableA y TableMatched, había una tabla que definía las filas que deberían existir en TableMatched para cada fila en TableA. Vamos a llamarlo TableMatchedDomain.

continuación, la aplicación visitada TableMatched través de una vista que controlaba las filas devueltas, como este:

create view TableMatchedView 
select a.ID, 
     d.Number, 
     m.OtherValues  
from TableA a 
     join TableMatchedDomain d 
     left join TableMatched m on m.ID = a.ID and m.Number = d.Number 

De esta manera, las filas devueltas siempre eran correctas. Si faltaban filas de TableMatched, los Números se devolvían pero con OtherValues ​​como null. Si había valores adicionales en TableMatched, entonces no se devolvieron en absoluto, como si no existieran. Al cambiar las filas en TableMatchedDomain, este comportamiento podría controlarse muy fácilmente. Si se eliminara un valor de TableMatchedDomain, desaparecería de la vista.Si se volvió a agregar en el futuro, los otros valores correspondientes aparecerán nuevamente como antes.

La razón por la que he diseñado de esta manera fue que sentí que el establecimiento de un invarient de la configuración fila de TableMatched era demasiado frágil y, peor aún, introduce redundancia. Así que eliminé la restricción de los grupos de filas (en TableMatched) y en su lugar hice que todo el contenido de otra tabla (TableMatchedDomain) definiera la forma correcta de los datos.

Cuestiones relacionadas