2009-02-26 22 views
33

Necesito encontrar una declaración de selección que me devolverá un registro que coincida exactamente con mi entrada, o la coincidencia más cercana si no se encuentra una coincidencia exacta.Buscar el valor numérico más cercano en la base de datos

Aquí está mi declaración seleccionada hasta el momento.

SELECT * FROM [myTable] 
WHERE Name = 'Test' AND Size = 2 AND PType = 'p' 
ORDER BY Area DESC 

Lo que necesito hacer es encontrar el valor más cercano al campo 'Area', por lo que si mi entrada es de 1,125 y la base de datos contiene 2, 1,5, 1 y 0,5 la consulta devolverá el registro que contiene 1

Mis habilidades SQL son muy limitadas por lo que cualquier ayuda sería apreciada.

Respuesta

56

obtener la diferencia entre el área y la entrada, toma valor absoluto por lo que siempre, entonces ascendente orden positivo y tomar la primera

SELECT TOP 1 * FROM [myTable] 
WHERE Name = 'Test' and Size = 2 and PType = 'p' 
ORDER BY ABS(Area - @input) 
2

Cómo acerca de la adquisición por la diferencia entre su entrada y [Espacio], tales como:

DECLARE @InputValue DECIMAL(7, 3) 

SET @InputValue = 1.125 

SELECT TOP 1 * FROM [myTable] 
WHERE Name = 'Test' AND Size = 2 AND PType = 'p' 
ORDER BY ABS(@InputValue - Area) 
0

Si el uso de MySQL

SELECT * FROM [myTable] ... ORDER BY ABS(Area - SuppliedValue) LIMIT 1 
7

algo horrible, a lo largo de las líneas de:

ORDER BY ABS(Area - 1.125) ASC LIMIT 1 

¿Quizás?

2
SELECT * 
    FROM [myTable] 
    WHERE Name = 'Test' AND Size = 2 AND PType = 'p' 
    ORDER BY ABS(Area - 1.125) 
    LIMIT 1 

- MarkusQ

1

en cuenta que aunque ABS() es compatible con casi todo, técnicamente no es estándar (en SQL99 por lo menos). Si tiene que escribir ANSI SQL estándar, por alguna razón, usted tendría que solucionar el problema con un operador CASO:

SELECT * FROM myTable 
WHERE Name='Test' AND Size=2 AND PType='p' 
ORDER BY CASE Area>1.125 WHEN 1 THEN Area-1.125 ELSE 1.125-Area END 
2

Si tiene muchas filas que satisfacen la igualdad entre los predicados en Name, Size y PType columnas entonces es posible que desee incluir predicados de rango en la columna Area en su consulta. Si la columna Area está indexada, esto podría permitir un acceso basado en índices eficiente.

la siguiente consulta (escrito utilizando la sintaxis de Oracle) utiliza una rama de un UNION ALL para encontrar el registro con un mínimo Area >= su objetivo, mientras que la otra rama encuentra el registro de la máxima Area < su objetivo. Uno de estos dos registros será el registro que está buscando. Luego puede ORDER BY ABS(Area - ?input) para elegir al ganador entre esos dos candidatos. Lamentablemente, la consulta es compleja debido a SELECTS anidados que son necesarios para aplicar la precedencia de ROWNUM/ORDER BY deseada.

SELECT * 
FROM 
    (SELECT * FROM 
    (SELECT * FROM 
     (SELECT * FROM [myTable] 
     WHERE Name = 'Test' AND Size = 2 AND PType = 'p' AND Area >= ?target 
     ORDER BY Area) 
     WHERE ROWNUM < 2 
    UNION ALL 
    SELECT * FROM 
     (SELECT * FROM [myTable] 
     WHERE Name = 'Test' AND Size = 2 AND PType = 'p' AND Area < ?target 
     ORDER BY Area DESC) 
     WHERE ROWNUM < 2) 
    ORDER BY ABS(Area - ?target)) 
WHERE rownum < 2 

Un buen índice para esta consulta sería (Name, Size, PType, Area), en cuyo caso el plan de ejecución de la consulta se espera se basa en dos exploraciones rango de índices que cada devolvió una sola fila.

-2

Seleccione el minuto en que [campo]> your_target_value Seleccione al máximo, donde [campo] < your_target_value

+1

Bienvenido a SO y gracias por tratar de contribuir! Pero hay algunas cosas que mejorar en su respuesta para ser útil.Primero, el marcado está roto. Los bloques de código deben sangrar por 4 espacios, ver [ayuda de edición] (http://stackoverflow.com/editing-help). Aparte de esto, una explicación sería útil ya que las respuestas de solo código son generalmente difíciles de entender. Establecer que tu respuesta es pseudocódigo SQL o reescribirlo en SQL regular también sería bueno. Aún así, su respuesta es útil y después de eliminar los problemas, puede subir de categoría. – Palec

Cuestiones relacionadas