top ejemplos all sql-server sql-order-by union

sql-server - ejemplos - select union sql server



SQL: utilizando Top 1 en la consulta UNION con orden por (4)

Creo que las consultas anteriores excluyen el 01/05/2009 al utilizar <y> en lugar de <= y> =.

Tengo una mesa como abajo

Rate Effective_Date ---- -------------- 5.6 02/02/2009 5.8 05/01/2009 5.4 06/01/2009 5.8 12/01/2009 6.0 03/15/2009

Se supone que debo encontrar todas las tarifas vigentes para la fecha actual y posteriores. Así que para obtener la tasa efectiva actual, yo uso

SELECT TOP 1 * from table where effective_date < ''05/05/2009'' order by effective date desc

para las tarifas después de la fecha actual la consulta es

SELECT * from table where effective_date > ''05/05/2009''

Para combinar estos dos resultados utilizo un sindicato como

SELECT TOP 1 * from table where effective_date < ''05/05/2009'' order by effective date desc UNION SELECT * from table where effective_date > ''05/05/2009''

El resultado esperado es

Rate Effective Date ---- -------------- 5.8 05/01/2009 5.4 06/01/2009 5.8 12/01/2009 6.0 03/15/2009

Pero me sale el resultado real como

Rate Effective Date ---- -------------- 5.6 02/02/2009 5.4 06/01/2009 5.8 12/01/2009 6.0 03/15/2009

No tengo ni idea de por qué sucede esto? ¿Alguna sugerencia?


Funciona de esta manera:

select * from ( select top 1 * from table where effective_date <= ''05/05/2009'' order by effective_date desc ) as current_rate union all select * from table where effective_date > ''05/05/2009''


La Orden por en una declaración de selección que forma parte de una unión se ignora. Por lo tanto, su TOP 1 está seleccionando algún registro arbitrario (probablemente el primer registro por la clave agrupada para la tabla).


La orden por no es válida cuando se usa con una unión ...

Hice un trabajo rápido y sucio usando Common Table Expression con algunos trucos de enunciado de Rango y Caso para obtener los resultados que buscabas ...

WITH CTE_RATES ( RATE, EFFECTIVE_DATE, CUR, SORT ) AS ( SELECT Rate, Effective_date, CASE WHEN Effective_date > ''5/5/2009'' THEN 1 ELSE 0 END, RANK() OVER (PARTITION BY CASE WHEN EFFECTIVE_DATE > ''5/5/2009'' THEN 1 ELSE 0 END ORDER BY EFFECTIVE_DATE DESC) FROM TestTable ) SELECT RATE, EFFECTIVE_DATE FROM ( SELECT RATE, EFFECTIVE_DATE FROM CTE_RATES WHERE CUR = 0 AND SORT = 1 UNION ALL SELECT RATE, EFFECTIVE_DATE FROM CTE_RATES WHERE CUR = 1 ) AS QRY ORDER BY EFFECTIVE_DATE

Para explicar lo que está pasando ...

El CTE define los indicadores de tasa, fecha, actual y ordenación devueltos de la consulta ...

El CASO separa los resultados en aquellos que son anteriores a la fecha de búsqueda, y aquellos que están después de la fecha de búsqueda. Usamos los resultados del caso (Cur) en nuestra unión para extraer los resultados de la lista dividida.

La función Rank () luego ordena la lista mediante la creación de una partición en el mismo criterio que la declaración CASE utiliza para separar la lista ... luego ordenamos por fecha efectiva de manera descendente. Esto tomará la lista de "pasado" y hará que sea la más actual "pasada" entrada rango 1 ...

Luego en la parte de la unión de la consulta ..

En la parte superior, obtenemos el rango y la fecha de la lista de "pasado" (cur = 0) y la primera entrada en la lista de "pasado" .. (sort = 1) .. que devolverá 1 registro (o 0 si no hay registros anteriores a la fecha de búsqueda) ..

Luego unimos eso con todo el registro de la lista "actual" (cur = 1)

Luego, finalmente ... tomamos los RESULTADOS de la UNIÓN ... y ordenamos que para la fecha de vigencia nos den todos los registros actuales y el registro anterior "más reciente".