ADVERTENCIA SOBRE SOLUCIONES:
MUCHAS SOLUCIONES EXISTENTES PROPORCIONARÁN LA SALIDA INCORRECTA SI LAS FILAS NO SON ÚNICAS
Si usted es la única persona que crea tablas, esto puede no ser relevante, pero varias soluciones le darán un número diferente de filas de salida del código en cuestión, cuando una de las tablas puede no contener filas únicas.
ADVERTENCIA SOBRE LA DECLARACIÓN DEL PROBLEMA:
CON MÚLTIPLES COLUMNAS NO EXISTE, PIENSA CUIDADOSAMENTE LO QUE QUIERES
Cuando veo una entrada con dos columnas, puedo imaginar que significa dos cosas:
- El valor de la columna a y la columna b aparecen en la otra tabla independientemente
- Los valores de la columna a y la columna b aparecen juntos en la otra tabla en la misma fila
El escenario 1 es bastante trivial, simplemente use dos declaraciones IN.
En línea con la mayoría de las respuestas existentes, por la presente proporciono una visión general de los enfoques mencionados y adicionales para el Escenario 2 (y un breve juicio):
EXISTE (Seguro, recomendado para SQL Server)
Según lo provisto por @mrdenny, EXISTS suena exactamente como lo que está buscando, aquí está su ejemplo:
SELECT * FROM T1
WHERE EXISTS
(SELECT * FROM T2
WHERE T1.a=T2.a and T1.b=T2.b)
IZQUIERDA SEMI UNIR (Seguro, recomendado para dialectos que lo soporten)
Esta es una forma muy concisa de unirse, pero desafortunadamente la mayoría de los dialectos de SQL, incluido el servidor SQL, actualmente no lo admiten.
SELECT * FROM T1
LEFT SEMI JOIN T2 ON T1.a=T2.a and T1.b=T2.b
Múltiples declaraciones IN (seguro, pero tenga cuidado con la duplicación de código)
Como mencionó @cataclysm, usar dos declaraciones IN también puede ser útil, tal vez incluso supere a las otras soluciones. Sin embargo, debe tener mucho cuidado con la duplicación de código. Si alguna vez desea seleccionar de una tabla diferente o cambiar la instrucción where, es un riesgo mayor que cree inconsistencias en su lógica.
Solución básica
SELECT * from T1
WHERE a IN (SELECT a FROM T2 WHERE something)
AND b IN (SELECT b FROM T2 WHERE something)
Solución sin duplicación de código (creo que esto no funciona en consultas regulares de SQL Server)
WITH mytmp AS (SELECT a, b FROM T2 WHERE something);
SELECT * from T1
WHERE a IN (SELECT a FROM mytmp)
AND b IN (SELECT b FROM mytmp)
UNIÓN INTERNA (técnicamente se puede hacer seguro, pero a menudo esto no se hace)
La razón por la que no recomiendo usar una unión interna como filtro es porque, en la práctica, las personas a menudo permiten que los duplicados en la tabla derecha causen duplicados en la tabla izquierda. Y para empeorar las cosas, a veces hacen que el resultado final sea distinto, mientras que la tabla de la izquierda en realidad puede no necesitar ser única (o no única en las columnas que seleccione). Además, le da la oportunidad de seleccionar realmente una columna que no existe en la tabla de la izquierda.
SELECT T1.* FROM T1
INNER JOIN
(SELECT DISTINCT a, b FROM T2) AS T2sub
ON T1.a=T2sub.a AND T1.b=T2sub.b
Errores más comunes:
- Unirse directamente en T2, sin una subconsulta segura. Resultando en el riesgo de duplicación)
- SELECT * (Guaranateed para obtener columnas de T2)
- SELECCIONAR c (no garantiza que su columna venga y siempre venga de T1)
- No DISTINCT o DISTINCT en el lugar equivocado
CONCATENACIÓN DE COLUMNAS CON SEPARADOR (No muy seguro, rendimiento horrible)
El problema funcional es que si usa un separador que puede aparecer en una columna, se vuelve difícil asegurarse de que el resultado sea 100% exacto. El problema técnico es que este método a menudo incurre en conversiones de tipos e ignora completamente los índices, lo que resulta en un rendimiento posiblemente horrible. A pesar de estos problemas, tengo que admitir que a veces todavía lo uso para consultas ad-hoc en pequeños conjuntos de datos.
SELECT * FROM T1
WHERE CONCAT(a,"_",b) IN
(SELECT CONCAT(a,"_",b) FROM T2)
Tenga en cuenta que si sus columnas son numéricas, algunos dialectos SQL requerirán que los convierta primero en cadenas. Creo que el servidor SQL hará esto automáticamente.
Para concluir: Como es habitual, hay muchas maneras de hacer esto en SQL, usar opciones seguras evitará sorpresas y le ahorrará tiempo y dolores de cabeza a largo plazo.