De preferência, eu gostaria de alterar a tabela para armazenar datetime2
valores em vez de complicada época de lixo.
Mas, supondo que você não pode corrigir o design...
Para Larnu ponto, você não deseja aplicar cálculos para a coluna, e você definitivamente não deseja aplicar FORMAT()
para ambos os lados, porque FORMAT()
é um absoluto cão.
Em vez disso, eu gostaria de encontrar os limites para os dias de hoje, e usar um intervalo ilimitado. Isso pressupõe que o TS
coluna deve ser bigint
:
DECLARE @d date = GETDATE();
DECLARE @start bigint = DATEDIFF(SECOND, '19700101', @d),
@end bigint = DATEDIFF(SECOND, '19700101', DATEADD(DAY, 1, @d));
SELECT COUNT(*) AS c
FROM dbo.[TABLE]
WHERE TS >= @start * 1000
AND TS < @end * 1000;
Isso evita qualquer tipo de formatação sobrecarga, complicado e desnecessário converter expressões (TS
já deve ser um bigint
, bem, então por que o explícito CONVERT()
?).
Se você precisa de datas não-contíguas, ok, ainda podemos fazer isso com muito menos o abuso da mesa. Basta criar uma tabela #temp ou a variável de tabela com colunas calculadas, insira suas datas de lá e, em seguida, associação externa a ele.
DECLARE @d table
(
d datetime2,
s AS CONVERT(bigint,
DATEDIFF(SECOND, '19700101', d)) * 1000,
e AS CONVERT(bigint,
DATEDIFF(SECOND, '19700101', DATEADD(DAY, 1, d))) * 1000
);
INSERT @d(d) VALUES('20211123'),('20211007');
-- if you want a row per day:
SELECT d.d, COUNT(t.TS) AS c
FROM @d AS d
LEFT OUTER JOIN dbo.[TABLE] AS t
ON t.TS >= d.s
AND t.TS < d.e
GROUP BY d.d
ORDER BY d.d;
-- if you just want a total count:
SELECT COUNT(t.TS) AS c
FROM @d AS d
LEFT OUTER JOIN dbo.[TABLE] AS t
ON t.TS >= d.s
AND t.TS < d.e;
Muito mais na data de maus hábitos e práticas recomendadas: