Verilerin tek bir sütunda depolanması, ayrılmaz bir şekilde bağlantılı oldukları için tercih edilen yoldur. Zamandaki nokta, iki değil, tek bir bilgidir.
Birçok ürün tarafından "perde arkasında" kullanılan tarih / saat verisini depolamanın yaygın bir yolu, "tarih" ondalık değerin tamsayı kısmı ve "saat" in kesirli olduğu ondalık bir değere dönüştürmektir. değer. Böylece, 1900-01-01 00:00:00 0.0, 20 Eylül 2016 9:34:00 42631.39861 olarak saklanır. 42631, 1900-01-01'den bu yana geçen gün sayısıdır. .39861, gece yarısından bu yana geçen süredir. Bunu yapmak için doğrudan ondalık türü kullanmayın, açık bir tarih / saat türü kullanın; buradaki amacım sadece bir örnek.
Verilerin iki ayrı sütunda depolanması, belirli bir zaman noktasının depolanan değerden daha erken veya daha sonra olup olmadığını görmek istediğinizde her iki sütun değerini birleştirmeniz gerektiği anlamına gelir.
Değerleri ayrı ayrı saklarsanız, algılanması zor "hatalara" rastlarsınız. Örneğin aşağıdakileri ele alalım:
IF OBJECT_ID('tempdb..#DT') IS NOT NULL
DROP TABLE #DT;
CREATE TABLE #DT
(
dt_value DATETIME NOT NULL
, d_value DATE NOT NULL
, t_value TIME(0) NOT NULL
);
DECLARE @d DATETIME = '2016-09-20 09:34:00';
INSERT INTO #DT (dt_value, d_value, t_value)
SELECT @d, CONVERT(DATE, @d), CONVERT(TIME(0), @d);
SET @d = '2016-09-20 11:34:00';
INSERT INTO #DT (dt_value, d_value, t_value)
SELECT @d, CONVERT(DATE, @d), CONVERT(TIME(0), @d);
/* show all rows with a date after 2016-07-01 11:00 am */
SELECT *
FROM #DT dt
WHERE dt.dt_value >= '2016-07-01 11:00:00';
/* show all rows with a date after 2016-07-01 11:00 am */
SELECT *
FROM #DT dt
WHERE dt.d_value >= CONVERT(DATE, '2016-07-01')
AND dt.t_value >= CONVERT(TIME(0), '11:00:00');
Yukarıdaki kodda, iki değerle dolduran bir test tablosu oluşturuyoruz, ardından bu verilere karşı basit bir sorgu gerçekleştiriyoruz. Birincisi SELECT
her iki satırı da döndürür, ancak ikincisi SELECT
yalnızca tek bir satır döndürür, bu da istenen sonuç olmayabilir:
Yorumlarda @ ypercube tarafından işaret edildiği gibi, değerlerin ayrı sütunlarda olduğu bir tarih / saat aralığını filtrelemenin doğru yolu:
WHERE dt.d_value > CONVERT(DATE, '2016-07-01') /* note there is no time component here */
OR (
dt.d_value = CONVERT(DATE, '2016-07-01')
AND dt.t_value >= CONVERT(TIME(0), '11:00:00')
)
Analiz amacıyla ayrılmış zaman bileşenine ihtiyacınız varsa , değerin zaman bölümü için hesaplanmış, kalıcı bir sütun eklemeyi düşünebilirsiniz:
ALTER TABLE #DT
ADD dt_value_time AS CONVERT(TIME(0), dt_value) PERSISTED;
SELECT *
FROM #dt;
Kalıcı sütun daha sonra günün saatine göre hızlı çeşitlere vb. İzin verecek şekilde dizine eklenebilir.
Tarih ve saati görüntüleme amacıyla iki alana ayırmayı düşünüyorsanız, biçimlendirmenin sunucuda değil istemcide yapılması gerektiğini fark etmelisiniz.