Предпочтительно, я бы поменял таблицу для хранения datetime2
ценности вместо запутанного хлама эпохи.
Но, предполагая, что вы не можете исправить дизайн...
По мнению Ларну, вы не хотите применять вычисления к столбцу, и вы определенно не хотите применять FORMAT()
с обеих сторон, потому чтоFORMAT()
это абсолютная собака.
Вместо этого я бы нашел границы на сегодня и использовал открытый диапазон. Это предполагает, что TS
колонка должна быть 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;
Это позволяет избежать любых накладных расходов на форматирование, запутанных и ненужных выражений преобразования (TS
должно быть, уже есть bigint
, верно, так почему же явное CONVERT()
?).
Если вам нужны несмежные даты, хорошо, мы все еще можем сделать это с гораздо меньшим злоупотреблением таблицей. Просто создайте таблицу #temp или переменную таблицы с вычисляемыми столбцами, вставьте туда несколько ваших дат, а затем внешне присоединитесь к ней.
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;
Гораздо больше о современных вредных привычках и лучших практиках: