范围内的日期问题
Issue with dates in a range
鉴于以下 SQL,我遇到了一个问题:
根据开始日期 (@fi) 和结束日期 (@ff),有时 returns 值,有时不是。
例如:
1) 如果@fi 和@ff 是 '01/01/2014' -> ok
2)if @fi and @ff are '01/01/2015' -> ok
3)if @fi and @ff are '31/12/2014' -> no rows
4)if @fi = '31/12/2014' and @ff = '01/01/2015' -> ok (but returns more rows than the second case, that is, there should be results for the third case).
I've tried with BETWEEN clause, with the same result. I checked (in the 3rd case) if the is included in that range (with an if-else), and yes, it is. Any clue?
提前致谢。
问候。
declare @fi date,
@ff date
set @fi = '31/12/2014'
set @ff = '01/01/2015'
SELECT Registro, Area, Grupo, Codigo, Asunto, Año, Total, IdArea, IdGrupo
FROM
(SELECT TOP (100) PERCENT TM2000_RegistrosAsuntos.Registro,
TM2000_Areas.Area, TM2000_Grupos.Grupo,
TM2000_Asuntos.Codigo, TM2000_Asuntos.Asunto,
SUM(CAST(CASE WHEN FechaDocumento >= @FI
AND FechaDocumento <= @FF THEN 1 ELSE 0 END
AS integer))
AS Año, COUNT(TM2000_RegistroGeneral.Id) AS Total,
TM2000_Asuntos.IdArea, TM2000_Asuntos.IdGrupo
FROM TM2000_RegistroGeneral
INNER JOIN TM2000_Asuntos ON
TM2000_RegistroGeneral.IdAsunto = TM2000_Asuntos.Codigo
INNER JOIN
TM2000_Areas ON TM2000_Asuntos.IdArea = TM2000_Areas.Id
INNER JOIN
TM2000_Grupos ON TM2000_Asuntos.IdGrupo = TM2000_Grupos.Id AND TM2000_Asuntos.IdArea = TM2000_Grupos.IdArea
INNER JOIN
TM2000_RegistrosAsuntos ON TM2000_RegistroGeneral.TipoRegistro = TM2000_RegistrosAsuntos.Id
WHERE (TM2000_RegistroGeneral.FechaDocumento >= @FI
AND TM2000_RegistroGeneral.FechaDocumento <= @FF)
AND (ISNULL(TM2000_Asuntos.CodigoNulo, 0) = 0)
OR (TM2000_RegistroGeneral.FechaDocumento >= DATEADD(YEAR, - 1, @FI)
AND TM2000_RegistroGeneral.FechaDocumento <= DATEADD(YEAR, - 1, @FF))
AND (ISNULL(TM2000_Asuntos.CodigoNulo, 0) = 0)
OR (TM2000_RegistroGeneral.FechaDocumento >= DATEADD(YEAR, - 2, @FI)
AND TM2000_RegistroGeneral.FechaDocumento <= DATEADD(YEAR, - 2, @FF))
AND (ISNULL(TM2000_Asuntos.CodigoNulo, 0) = 0)
OR (TM2000_RegistroGeneral.FechaDocumento >= DATEADD(YEAR, - 3, @FI)
AND TM2000_RegistroGeneral.FechaDocumento <= DATEADD(YEAR, - 3, @FF))
AND (ISNULL(TM2000_Asuntos.CodigoNulo, 0) = 0)
OR (TM2000_RegistroGeneral.FechaDocumento >= DATEADD(YEAR, - 4, @FI)
AND TM2000_RegistroGeneral.FechaDocumento <= DATEADD(YEAR, - 4, @FF))
AND (ISNULL(TM2000_Asuntos.CodigoNulo, 0) = 0)
GROUP BY TM2000_Asuntos.Asunto, TM2000_Asuntos.IdArea, TM2000_Asuntos.IdGrupo, TM2000_Asuntos.Codigo, TM2000_Areas.Area, TM2000_Grupos.Grupo,
TM2000_RegistrosAsuntos.Registro
ORDER BY TM2000_RegistrosAsuntos.Registro, TM2000_Asuntos.IdArea, TM2000_Asuntos.IdGrupo) AS TBase
用这个替换你的 where 子句。
WHERE (( TM2000_RegistroGeneral.FechaDocumento >= @fi
AND TM2000_RegistroGeneral.FechaDocumento <= @ff )
OR ( TM2000_RegistroGeneral.FechaDocumento >= DATEADD(YEAR, -1, @fi)
AND TM2000_RegistroGeneral.FechaDocumento <= DATEADD(YEAR, -1, @ff) )
OR ( TM2000_RegistroGeneral.FechaDocumento >= DATEADD(YEAR, -2, @fi)
AND TM2000_RegistroGeneral.FechaDocumento <= DATEADD(YEAR, -2, @ff) )
OR ( TM2000_RegistroGeneral.FechaDocumento >= DATEADD(YEAR, -3, @fi)
AND TM2000_RegistroGeneral.FechaDocumento <= DATEADD(YEAR, -3, @ff) )
OR ( TM2000_RegistroGeneral.FechaDocumento >= DATEADD(YEAR, -4, @fi)
AND TM2000_RegistroGeneral.FechaDocumento <= DATEADD(YEAR, -4, @ff) )
)
AND ( ISNULL(TM2000_Asuntos.CodigoNulo, 0) = 0 )
我相信您的 OR & AND 相互冲突并且您不必要地重复了 AND 子句
在 WHERE 子句中比较时使用 CAST(DATE, TM2000_RegistroGeneral.FechaDocumento) 解决了问题。
FechaDocumento 是 DATETIME,因此需要转换。
谢谢!
鉴于以下 SQL,我遇到了一个问题: 根据开始日期 (@fi) 和结束日期 (@ff),有时 returns 值,有时不是。
例如: 1) 如果@fi 和@ff 是 '01/01/2014' -> ok
2)if @fi and @ff are '01/01/2015' -> ok
3)if @fi and @ff are '31/12/2014' -> no rows
4)if @fi = '31/12/2014' and @ff = '01/01/2015' -> ok (but returns more rows than the second case, that is, there should be results for the third case).
I've tried with BETWEEN clause, with the same result. I checked (in the 3rd case) if the is included in that range (with an if-else), and yes, it is. Any clue?
提前致谢。 问候。
declare @fi date,
@ff date
set @fi = '31/12/2014'
set @ff = '01/01/2015'
SELECT Registro, Area, Grupo, Codigo, Asunto, Año, Total, IdArea, IdGrupo
FROM
(SELECT TOP (100) PERCENT TM2000_RegistrosAsuntos.Registro,
TM2000_Areas.Area, TM2000_Grupos.Grupo,
TM2000_Asuntos.Codigo, TM2000_Asuntos.Asunto,
SUM(CAST(CASE WHEN FechaDocumento >= @FI
AND FechaDocumento <= @FF THEN 1 ELSE 0 END
AS integer))
AS Año, COUNT(TM2000_RegistroGeneral.Id) AS Total,
TM2000_Asuntos.IdArea, TM2000_Asuntos.IdGrupo
FROM TM2000_RegistroGeneral
INNER JOIN TM2000_Asuntos ON
TM2000_RegistroGeneral.IdAsunto = TM2000_Asuntos.Codigo
INNER JOIN
TM2000_Areas ON TM2000_Asuntos.IdArea = TM2000_Areas.Id
INNER JOIN
TM2000_Grupos ON TM2000_Asuntos.IdGrupo = TM2000_Grupos.Id AND TM2000_Asuntos.IdArea = TM2000_Grupos.IdArea
INNER JOIN
TM2000_RegistrosAsuntos ON TM2000_RegistroGeneral.TipoRegistro = TM2000_RegistrosAsuntos.Id
WHERE (TM2000_RegistroGeneral.FechaDocumento >= @FI
AND TM2000_RegistroGeneral.FechaDocumento <= @FF)
AND (ISNULL(TM2000_Asuntos.CodigoNulo, 0) = 0)
OR (TM2000_RegistroGeneral.FechaDocumento >= DATEADD(YEAR, - 1, @FI)
AND TM2000_RegistroGeneral.FechaDocumento <= DATEADD(YEAR, - 1, @FF))
AND (ISNULL(TM2000_Asuntos.CodigoNulo, 0) = 0)
OR (TM2000_RegistroGeneral.FechaDocumento >= DATEADD(YEAR, - 2, @FI)
AND TM2000_RegistroGeneral.FechaDocumento <= DATEADD(YEAR, - 2, @FF))
AND (ISNULL(TM2000_Asuntos.CodigoNulo, 0) = 0)
OR (TM2000_RegistroGeneral.FechaDocumento >= DATEADD(YEAR, - 3, @FI)
AND TM2000_RegistroGeneral.FechaDocumento <= DATEADD(YEAR, - 3, @FF))
AND (ISNULL(TM2000_Asuntos.CodigoNulo, 0) = 0)
OR (TM2000_RegistroGeneral.FechaDocumento >= DATEADD(YEAR, - 4, @FI)
AND TM2000_RegistroGeneral.FechaDocumento <= DATEADD(YEAR, - 4, @FF))
AND (ISNULL(TM2000_Asuntos.CodigoNulo, 0) = 0)
GROUP BY TM2000_Asuntos.Asunto, TM2000_Asuntos.IdArea, TM2000_Asuntos.IdGrupo, TM2000_Asuntos.Codigo, TM2000_Areas.Area, TM2000_Grupos.Grupo,
TM2000_RegistrosAsuntos.Registro
ORDER BY TM2000_RegistrosAsuntos.Registro, TM2000_Asuntos.IdArea, TM2000_Asuntos.IdGrupo) AS TBase
用这个替换你的 where 子句。
WHERE (( TM2000_RegistroGeneral.FechaDocumento >= @fi
AND TM2000_RegistroGeneral.FechaDocumento <= @ff )
OR ( TM2000_RegistroGeneral.FechaDocumento >= DATEADD(YEAR, -1, @fi)
AND TM2000_RegistroGeneral.FechaDocumento <= DATEADD(YEAR, -1, @ff) )
OR ( TM2000_RegistroGeneral.FechaDocumento >= DATEADD(YEAR, -2, @fi)
AND TM2000_RegistroGeneral.FechaDocumento <= DATEADD(YEAR, -2, @ff) )
OR ( TM2000_RegistroGeneral.FechaDocumento >= DATEADD(YEAR, -3, @fi)
AND TM2000_RegistroGeneral.FechaDocumento <= DATEADD(YEAR, -3, @ff) )
OR ( TM2000_RegistroGeneral.FechaDocumento >= DATEADD(YEAR, -4, @fi)
AND TM2000_RegistroGeneral.FechaDocumento <= DATEADD(YEAR, -4, @ff) )
)
AND ( ISNULL(TM2000_Asuntos.CodigoNulo, 0) = 0 )
我相信您的 OR & AND 相互冲突并且您不必要地重复了 AND 子句
在 WHERE 子句中比较时使用 CAST(DATE, TM2000_RegistroGeneral.FechaDocumento) 解决了问题。
FechaDocumento 是 DATETIME,因此需要转换。
谢谢!