Najlepiej, ja bym zmienił tabelę do przechowywania datetime2
wartości, zamiast skomplikowanych śmieci epoki.
Ale, zakładając, że nie możesz naprawić projekt...
Zdaniem Ларну, nie chcesz stosować obliczenia do kolumny, i na pewno nie chcesz stosować FORMAT()
z obu stron, boFORMAT()
to absolutna pies.
Zamiast tego bym znalazł granicy na dziś i wykorzystał odkryty zakres. To sugeruje, że TS
kolumna musi być 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;
Pozwala to uniknąć kosztów ogólnych na formatowanie, skomplikowanych i niepotrzebnych zwrotów konwersji (TS
musi być, już jest bigint
prawda , więc dlaczego bezpośrednia CONVERT()
?).
Jeśli potrzebujesz nieprzylegające chcesz, dobrze, wciąż możemy zrobić to z o wiele mniejszym nadużyciem tabeli. Wystarczy utworzyć tabelę #temp lub zmiennej tabeli z obliczeniowe kolumnami, włóż tam kilka swoich dat, a następnie na zewnątrz dołącz do niej.
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;
Znacznie więcej na temat nowoczesnych szkodliwych nawyków i najlepszych praktykach: