rango - obtener mes y año de una fecha sql
Seleccionar fechas de inicio y finalización mal utilizadas de la tabla de instalaciones (6)
Estoy usando DB2, aunque una solución que use cualquier sabor de SQL probablemente me resulte lo suficientemente fácil de convertir.
No diseñé esta base de datos, o la aplicación que usa la base de datos. No tengo el poder de cambiar esta aplicación, cómo funciona o los datos. Debido a que desafía lo que considero un uso convencional de un inicio y una fecha de finalización, me cuesta escribir algo tan simple como seleccionar un punto específico en el tiempo.
Aquí están las partes relevantes / editadas de la tabla:
OBJECTID FACILITY_ID START_DATE END_DATE FACILITY_NAME
1001 500 1/1/1980 5/1/2000 Really Old Name
1002 500 1/1/1980 1/1/2006 Old Name
1003 500 1/1/1980 null Current Name
1004 501 1/1/1980 3/1/2008 Closed Facility Name
1004 502 1/1/1980 null Another Current Name
Lo que quiero devolver son los registros que son válidos para el 1 de julio de 2005:
OBJECTID FACILITY_ID START_DATE END_DATE FACILITY_NAME
1002 500 1/1/1980 1/1/2006 Old Name
1004 501 1/1/1980 3/1/2008 Closed Facility Name
1004 502 1/1/1980 null Another Current Name
Estoy tratando de evitar las subselecciones, pero entiendo que pueden ser necesarias. Si necesito una subselección, me gustaría mantenerlo limitado a uno. Buscar entre la fecha de inicio y la fecha de finalización no funciona, porque no devuelve instalaciones que tienen solo un registro con una fecha de finalización nula. Agregar una condición OR para incluir fechas de finalización que son nulas puede devolver más de un registro en algunos casos. Este problema parece tan simple en el servicio, que debo estar perdiendo una solución ridículamente obvia. ¿Alguien tiene alguna idea?
¿Funcionaría esto?
SELECT * FROM table_name
WHERE START_DATE < ''7/1/2005'' AND (END_DATE > ''7/1/2005'' OR END_DATE IS NULL);
El truco es fusionar la fecha de finalización con el día siguiente, :) Coalesce básicamente reemplaza un valor nulo con el segundo parámetro. Bonito pequeño truco.
select * from TAble where START_DATE < @DATE and Coalesce(END_DATE, @DATE+1) > @DATE
Perdón por responder mi propia pregunta. Gracias a todos, las respuestas dadas fueron muy útiles. También fue útil pensar exactamente lo que estaba tratando de lograr. Combinando conceptos de las respuestas que se dieron, pude encontrar algo que parece funcionar:
SELECT
*
FROM
FACILITY_TABLE
WHERE
(END_DATE IS NULL
AND OBJECTID NOT IN
(SELECT A.OBJECTID FROM FACILITY_TABLE A
WHERE ''7/1/2005'' BETWEEN A.BEGINDATE AND A.ENDDATE))
OR
''7/1/2005'' BETWEEN FACILITY_TABLE.START_DATE AND FACILITY_TABLE.ENDDATE
Como la fecha de inicio no tenía sentido para los datos, no la incluí. Devuelve solo los registros que fueron válidos en 7/1/2005 sin incluir también el registro actual si un registro expiró de aquí a entonces.
Por lo que nos has dado, esto es lo que quieres:
select * from facitities
where START_DATE <= @my_date and (@mydate <= END_DATE or END_DATE is null)
sin embargo, sospecho que lo sabías y quieres algo diferente, en cuyo caso, tendrás que ser más específico sobre lo que está mal con los datos.
Tomar 2:
select OBJECTID, FACILITY_ID, START_DATE, FACILITY_NAME, MIN(END_DATE) as END_DATE
from facitities
where START_DATE <= @my_date and (@mydate <= END_DATE or END_DATE is null)
group by OBJECTID, FACILITY_ID, START_DATE, FACILITY_NAME
Ligera variación de lo anterior:
select * from facilities
where @my_date between START_DATE AND COALESCE(END_DATE, CURRENT DATE)