Problema con consultas de SQL Server utilizando ENTRE en donde con DATETIME
-
13-09-2019 - |
Pregunta
Tengo un procedimiento almacenado que se repite a través de los meses del año fiscal y hace un recuento de los elementos de cada mes. Sé que es un hecho, hay 176 artículos, pero cuando corro este devuelve un recuento total de 182. He intentado eliminar un segundo del @EndDate, pero entonces mi recuento total fue de 165. Así que estoy bien contar los elementos dos veces, o sin contar todos ellos. ¿Alguien puede ayudar con lo que estoy haciendo mal aquí? A continuación se muestra una versión simplificada de lo que estoy haciendo:
DECLARE @Date DATETIME
DECLARE @EndDate DATETIME
SELECT @Date = CAST((@Year - 1) as VARCHAR) + '-07-01'
SELECT @EndDate = DATEADD(Month, 1, @Date)
DECLARE @Count INT
SELECT @Count = 0
WHILE @Count < 12
BEGIN
SELECT
COUNT(yai.ID)
FROM
table_1 yai
INNER JOIN table_2 yat ON yai.ID = yat.ID
WHERE
(yat.Date_Received BETWEEN CONVERT(VARCHAR, @Date, 101) AND CONVERT(VARCHAR, @EndDate, 101)) AND
yai.Pro_Type = @Value AND yat.Type = 'PC'
SELECT @Count = @Count + 1
SELECT @Date = DATEADD(MONTH, 1, @Date)
SELECT @EndDate = DATEADD(MONTH, 1, @EndDate)
END
Solución
A partir de la parte superior de mi cabeza.
SELECT DATEPART(month, yat.Date) as month, COUNT(yai.ID)
FROM table_1 yai
INNER JOIN table_2 yat ON yai.ID = yat.ID
WHERE
yai.Pro_Type = @Value AND yat.Type = 'PC'
AND DATEPART(year, yat.Date)=@Year
GROUP BY DATEPART(month, yat.Date)
ORDER BY DATEPART(month, yat.Date)
Otros consejos
El medio está incluido, por lo que su hijo de 1 segundo de resta debería estar allí (o incluso un día). Mi conjetura es que algunos no tienen Yais Yat correspondiente.
Editar: Su código es falso. No se puede hacer comparaciones diferentes a la igualdad con el formato 101.
Yo solía decir cosas raras como sé que es un hecho que hay 50 elementos y SQL ha devuelto 60 ...
Me enteré que estaba siempre mal! :)
Trate de separar el tiempo de los campos de fecha y hora:
DATEADD (d, DATEDIFF (d, 0, GetDate ()), 0)
No se pudo hacer esto en su lugar? La siguiente consulta le dará el recuento agrupados por mes. Si pones esto en una vista, a continuación, puede seleccionar entre la vista y el uso de una cláusula where para filtrar por el año y mes le interesa.
select year(yat.Date_Received) as year, month(yat.Date_Received) as month, count(*) as count
count(yai.ID)
from table_1 yai
inner join table_2 yat on yai.ID = yat.ID
where yai.Pro_Type = 'some_value'
and yat.Type = 'PC'
group by year(yat.Date_Received), month(yat.Date_Received)
Este es un caso clásico de un bucle innecesaria es el código SQL, pero si se quiere resolver esto con un bucle, cambie su selecto en el bucle de:
SELECT
COUNT(yai.ID)
a:
SELECT
@Date,@EndDate,*
y luego se ven en la salida y comprobar las filas devueltas
¿Por qué no convertir los meses del calendario en referencias absolutas enteros como esta:
DECLARE @BeginDate datetime = '7/1/2008'
DECLARE @EndDate datetime = '6/30/2009'
--
-- Convert calendar months into an absoulte integer:
--
DECLARE @BeginMonth int = (DatePart(year, @BeginDate) * 12) + DatePart(month, @BeginDate)
DECLARE @EndMonth int = (DatePart(year, @EndDate) * 12) + DatePart(month, @EndDate)
SELECT COUNT(yai.ID)
FROM table_1 yai
INNER JOIN table_2 yat ON yai.ID = yat.ID
WHERE (DatePart(year, yat.Date_Received) * 12) + DatePart(month, yat.Date_Received)
BETWEEN @BeginMonth AND @EndMonth)
AND yai.Pro_Type = @Value
AND yat.Type = 'PC'
Me encontrado esta pregunta porque tenía problemas con el uso de Fecha de cadena en consultas utilizando Entre y que estaba usando metadatos , mi compañero de trabajo me ayudó, así que espero que este le ayuda también:
N'convert(date,[fld_myDate]) Between convert(date,''01/01/2016'') AND convert(date,''08/26/2017'') '