2011-05-19 18 views
5

estoy bastante fuerte con SQL, pero no puedo pensar en una buena solución a este "similares" problema de análisis de datos:seleccionar filas con diferencia mínima

Dada una tabla con un conjunto de números enteros, lo es necesario que coincida cada entero con el entero en una segunda tabla que sea más similar (la diferencia absoluta más pequeña). Normalmente haré una unión cartesiana y ordenaré por la diferencia en números, pero solo necesito obtener un emparejamiento para cada fila de cada tabla, por lo que ningún valor de ninguna de las tablas puede usarse dos veces.

alguna idea de cómo lograr esto?

EDIT: Ejemplo:

TABLE_A

34 
57 
108 
219 
380 
5000 

TABLE_B

4000 
200 
400 
99 
40 
33 
34 
4600 

El emparejamiento sería una fila de TABLE_A y la fila más cercana de table_b:

RESULTADO

34,34 
57,40 
108,99 
219,200 
380,400 
5000,4600 

Así que hay una fila de cualquiera de las tablas aparece dos veces.

EDIT: aclaración más: estoy tratando de resolver este problema por el que da 1 fila de TABLE_A, nos encontramos con la fila 1 de table_b que está más cerca. Eso se convierte en un par y se elimina. Luego toma la siguiente fila de table_a y repite. Así que estamos tratando de encontrar la mejor coincidencia para cada fila y optimizar ese emparejamiento, sin tratar de optimizar las diferencias totales.

+0

"... una paridad para cada fila de cada tabla ..." es confuso. ¿Es "tomar todos los valores en la primera tabla y encontrar el más cercano en la segunda tabla"? ¿O hay algunos requisitos para que todos los valores de la segunda tabla aparezcan en la lista o de lo contrario deben aparecer en el conjunto final? Tal vez un pequeño ejemplo ayude –

+0

¿Puede agregar datos de muestra para ayudarnos a visualizar las entradas y salidas? ¿Podemos asumir que los enteros son únicos en cada tabla? ¿Qué pasa con 5 y 7 en una mesa, 6 en la otra? 6 debe aparecer dos veces porque está igualmente cerca de 5 y 7 – gbn

+0

Si está buscando la solución con la menor diferencia total entre conjuntos, entonces si tiene 5 y 8 en una tabla y 7 y 15 en la segunda tabla, entonces tus conjuntos serían en realidad (5,7), (8,15). Esto es cierto incluso aunque la diferencia más pequeña esté entre 7 y 8. Porque ((7-5) + (15-8)) == 9 pero ((8-7) + (15-5) == 11. Entonces el La solución que encuentre el número más cercano para esa fila no es necesariamente la solución óptima para el conjunto de datos. Realmente necesitamos saber cómo quiere priorizar la solución y resolver conflictos/duplicados como mencionó gbn. –

Respuesta

3

Suponiendo

donde da 1 fila de TABLE_A, encontramos la 1 fila de table_b que está más cerca

select 
    * 
from 
    TABLE_A a 
    cross apply 
    (select top 1 Number from TABLE_B b order by abs(b.Number - a.Number)) b2 

Esto también asume las filas de B puede ser repetidas: probarlo y mira si hace lo que quieres.Sin embargo, esto debería ajustarse a los datos de muestra para que responda a su pregunta ...

1
select v.* 
from 

    (select a.value as avalue, b.value as bvalue, 
    (abs(a.value - b.value)) as difference 
    from 
    TABLE_A a, 
    TABLE_B b) v, 

    (select a.value as avalue, b.value as bvalue, 
    min((abs(a.value - b.value))) as difference 
    from 
    TABLE_A a, 
    TABLE_B b 
    group by a.value, b.value) m 

where m.avalue = v.avalue and m.bvalue = v.value and m.difference = v.difference 
0

Es probable que necesite utilizar un cursor para manejar esto. Copie los datos de cada tabla en su propia tabla temporal y aplique su lógica una fila a la vez.

Lo que hace que esto sea difícil, si no imposible sin un cursor, es el hecho de que el orden en que usted maneja cada número de la primera tabla afectará el resultado final.

Si su primera tabla se parece a esto

9 
10 

Y el segundo cuadro se parece a esto

5 
6 

A continuación, el resultado se verá así si se procesa el 9 primero

9,6 
10,5 

Y el resultado sería así si se procesó el 10 primer

10,6 
9,5 
Cuestiones relacionadas