De préférence, je voudrais changer la table pour stocker les datetime2
les valeurs au lieu de alambiqué époque de la camelote.
Mais, en supposant que vous ne pouvez pas résoudre le design...
Pour Larnu point, vous ne voulez pas appliquer les calculs de la colonne, et vous ne voulez certainement pas à s'appliquer FORMAT()
des deux côtés, parce que FORMAT()
est un absolu chien.
Au lieu de cela, je voudrais trouver les limites pour aujourd'hui, et d'utiliser une plage ouverte. Ceci suppose que l' TS
la colonne doit être 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;
Cela évite toute mise en forme de la surcharge, compliquées et inutiles convertir des expressions (TS
doit déjà être un bigint
, droit, alors pourquoi explicite CONVERT()
?).
Si vous avez besoin non contigus dates, ok, on peut encore accomplir cela avec beaucoup moins d'abus de la table. Il suffit de créer une table #temp ou une variable de table avec des colonnes calculées, insérez vos dates multiples, et puis jointure externe pour elle.
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;
Beaucoup plus sur la date de mauvaises habitudes et pratiques exemplaires: