DATEADD (T-SQL)

Berlaku untuk:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse Analytics AnalyticsPlatform System (PDW)Titik akhir analitik SQL di Microsoft FabricWarehouse di Microsoft Fabric

Fungsi ini menambahkan angka (bilangan bulat yang ditandatangani) ke bagian tanggal input, dan mengembalikan nilai tanggal/waktu yang dimodifikasi. Misalnya, Anda dapat menggunakan fungsi ini untuk menemukan tanggal yaitu 7.000 menit dari hari ini: angka = 7000, datepart = menit, tanggal = hari ini.

Lihat Jenis dan fungsi data tanggal dan waktu untuk gambaran umum semua jenis dan fungsi data tanggal dan waktu Transact-SQL.

Konvensi sintaks transact-SQL

Sintaksis

DATEADD (datepart , number , date )

Catatan

Untuk melihat sintaks Transact-SQL untuk SQL Server 2014 (12.x) dan versi yang lebih lama, lihat Dokumentasi versi sebelumnya.

Argumen

datepart

Bagian tanggal yang DATEADD menambahkan angka int. Tabel ini mencantumkan semua argumen datepart yang valid.

Catatan

DATEADD tidak menerima variabel yang ditentukan pengguna yang setara untuk argumen datepart .

datepart Singkatan
year yy, yyyy
quarter qq, q
month mm, m
dayofyear dy, y
day dd, d
week wk, ww
weekday dw, w
hour hh
minute mi, n
second ss, s
millisecond ms
microsecond mcs
nanosecond ns

number

Ekspresi yang dapat mengatasi int yang DATEADD ditambahkan ke bagiantanggal. DATEADD menerima nilai variabel yang ditentukan pengguna untuk angka. DATEADDmemotong nilai angka tertentu yang memiliki pecahan desimal. Ini tidak membulatkan nilai angka dalam situasi ini.

date

Ekspresi yang bisa diatasi ke salah satu nilai berikut ini:

  • date
  • datetime
  • datetimeoffset
  • datetime2
  • smalldatetime
  • time

Untuk tanggal, DATEADD menerima ekspresi kolom, ekspresi, string literal, atau variabel yang ditentukan pengguna. Nilai literal string harus diselesaikan ke tanggalwaktu. Gunakan empat digit tahun untuk menghindari masalah ambiguitas. Lihat Mengonfigurasi cutoff dua digit tahun (opsi konfigurasi server) untuk informasi tentang tahun dua digit.

Jenis yang dikembalikan

Jenis data nilai yang dikembalikan untuk metode ini bersifat dinamis. Jenis pengembalian tergantung pada argumen yang disediakan untuk date. Jika nilai untuk date adalah tanggal harfiah string, DATEADD mengembalikan nilai tanggalwaktu . Jika jenis data input lain yang valid disediakan untuk date, DATEADD mengembalikan jenis data yang sama. DATEADD menimbulkan kesalahan jika skala detik harfiah string melebihi tiga posisi tempat desimal (.nnn) atau jika string literal berisi bagian offset zona waktu.

Nilai hasil

argumen datepart

dayofyear, day, dan weekday mengembalikan nilai yang sama.

Setiap datepart dan singkatannya mengembalikan nilai yang sama.

Jika berikut ini benar:

  • datepart adalah month
  • bulan tanggal memiliki lebih banyak hari daripada bulan pengembalian
  • hari tanggal tidak ada dalam bulan pengembalian

Kemudian, DATEADD mengembalikan hari terakhir dari bulan pengembalian. Misalnya, September memiliki 30 (tiga puluh) hari; oleh karena itu, pernyataan ini mengembalikan 2024-09-30 00:00:00.000:

SELECT DATEADD(month, 1, '20240830');
SELECT DATEADD(month, 1, '2024-08-31');

argumen angka

Argumen angka tidak boleh melebihi rentang int. Dalam pernyataan berikut, argumen untuk angka melebihi rentang int sebesar 1. Pernyataan ini mengembalikan pesan kesalahan berikut: Msg 8115, Level 16, State 2, Line 1. Arithmetic overflow error converting expression to data type int.

SELECT DATEADD(year, 2147483648, '20240731');
SELECT DATEADD(year, -2147483649, '20240731');

argumen tanggal

DATEADDtidak menerima argumen tanggal yang dinaikkan ke nilai di luar rentang jenis datanya. Dalam pernyataan berikut, nilai angka yang ditambahkan ke nilai tanggal melebihi rentang jenis data tanggal. DATEADD mengembalikan pesan kesalahan berikut: Msg 517, Level 16, State 1, Line 1 Adding a value to a 'datetime' column caused overflow.

SELECT DATEADD(year, 2147483647, '20240731');
SELECT DATEADD(year, -2147483647, '20240731');

Mengembalikan nilai untuk tanggal smalldatetime dan datepart detik atau pecahan

Bagian detik dari nilai smalldatetime selalu 00. Untuk nilai tanggal smalldatetime, berikut ini berlaku:

  • Untuk bagian tanggal second , dan nilai angka antara -30 dan +29, DATEADD tidak membuat perubahan.

  • Untuk bagian tanggal , dan nilai angka kurang dari -30, atau lebih dari +29, DATEADD melakukan penambahannyaseconddimulai pada satu menit.

  • Untuk bagian tanggalmillisecond dan nilai angka antara -30001 dan +29998, DATEADD tidak membuat perubahan.

  • Untuk bagian tanggal dan nilai angka kurang dari -30001, atau lebih dari +29998, DATEADD lakukan penambahannyamillisecond dimulai pada satu menit.

Keterangan

Gunakan DATEADD dalam klausa berikut:

  • GROUP BY
  • HAVING
  • ORDER BY
  • SELECT <list>
  • WHERE

Presisi detik pecahan

DATEADDtidak mengizinkan penambahan untuk tanggal atau microsecondnanosecond untuk jenis data tanggal smalldatetime, tanggal, dan tanggalwaktu.

Milidetik memiliki skala 3 (.123), mikrodetik memiliki skala 6 (.123456), dan nanodetik memiliki skala 9 (.123456789). Jenis data waktu, datetime2, dan datetimeoffset memiliki skala maksimum 7 (.1234567). Untuk bagian tanggalnanosecond, angka harus 100 sebelum detik pecahan tanggal meningkat. Angka antara 1 dan 49 membulatkan ke bawah ke 0, dan angka dari 50 hingga 99 membulatkan hingga 100.

Pernyataan ini menambahkan bagian tanggal dari millisecond, microsecond, atau nanosecond.

DECLARE @datetime2 DATETIME2 = '2024-01-01 13:10:10.1111111';

SELECT '1 millisecond', DATEADD(millisecond, 1, @datetime2)
UNION ALL
SELECT '2 milliseconds', DATEADD(millisecond, 2, @datetime2)
UNION ALL
SELECT '1 microsecond', DATEADD(microsecond, 1, @datetime2)
UNION ALL
SELECT '2 microseconds', DATEADD(microsecond, 2, @datetime2)
UNION ALL
SELECT '49 nanoseconds', DATEADD(nanosecond, 49, @datetime2)
UNION ALL
SELECT '50 nanoseconds', DATEADD(nanosecond, 50, @datetime2)
UNION ALL
SELECT '150 nanoseconds', DATEADD(nanosecond, 150, @datetime2);

Berikut adalah hasil yang ditetapkan.

1 millisecond     2024-01-01 13:10:10.1121111
2 milliseconds    2024-01-01 13:10:10.1131111
1 microsecond     2024-01-01 13:10:10.1111121
2 microseconds    2024-01-01 13:10:10.1111131
49 nanoseconds    2024-01-01 13:10:10.1111111
50 nanoseconds    2024-01-01 13:10:10.1111112
150 nanoseconds   2024-01-01 13:10:10.1111113

Offset zona waktu

DATEADD tidak mengizinkan penambahan untuk offset zona waktu.

Contoh

J. Tingkatkan datepart dengan interval 1

Masing-masing pernyataan ini kenaikan datepart dengan interval 1:

DECLARE @datetime2 DATETIME2 = '2024-01-01 13:10:10.1111111';

SELECT 'year', DATEADD(year, 1, @datetime2)
UNION ALL
SELECT 'quarter', DATEADD(quarter, 1, @datetime2)
UNION ALL
SELECT 'month', DATEADD(month, 1, @datetime2)
UNION ALL
SELECT 'dayofyear', DATEADD(dayofyear, 1, @datetime2)
UNION ALL
SELECT 'day', DATEADD(day, 1, @datetime2)
UNION ALL
SELECT 'week', DATEADD(week, 1, @datetime2)
UNION ALL
SELECT 'weekday', DATEADD(weekday, 1, @datetime2)
UNION ALL
SELECT 'hour', DATEADD(hour, 1, @datetime2)
UNION ALL
SELECT 'minute', DATEADD(minute, 1, @datetime2)
UNION ALL
SELECT 'second', DATEADD(second, 1, @datetime2)
UNION ALL
SELECT 'millisecond', DATEADD(millisecond, 1, @datetime2)
UNION ALL
SELECT 'microsecond', DATEADD(microsecond, 1, @datetime2)
UNION ALL
SELECT 'nanosecond', DATEADD(nanosecond, 1, @datetime2);

Berikut adalah hasil yang ditetapkan.

year         2025-01-01 13:10:10.1111111
quarter      2024-04-01 13:10:10.1111111
month        2024-02-01 13:10:10.1111111
dayofyear    2024-01-02 13:10:10.1111111
day          2024-01-02 13:10:10.1111111
week         2024-01-08 13:10:10.1111111
weekday      2024-01-02 13:10:10.1111111
hour         2024-01-01 14:10:10.1111111
minute       2024-01-01 13:11:10.1111111
second       2024-01-01 13:10:11.1111111
millisecond  2024-01-01 13:10:10.1121111
microsecond  2024-01-01 13:10:10.1111121
nanosecond   2024-01-01 13:10:10.1111111

B. Menaikkan lebih dari satu tingkat datepart dalam satu pernyataan

Masing-masing pernyataan ini menaikkan datepart dengan angka yang cukup besar untuk menambahkan dateparttanggal berikutnya yang lebih tinggi:

DECLARE @datetime2 DATETIME2;

SET @datetime2 = '2024-01-01 01:01:01.1111111';

--Statement                                 Result
-------------------------------------------------------------------
SELECT DATEADD(quarter, 4, @datetime2);     --2025-01-01 01:01:01.1111111
SELECT DATEADD(month, 13, @datetime2);      --2025-02-01 01:01:01.1111111
SELECT DATEADD(dayofyear, 365, @datetime2); --2025-01-01 01:01:01.1111111
SELECT DATEADD(day, 365, @datetime2);       --2025-01-01 01:01:01.1111111
SELECT DATEADD(week, 5, @datetime2);        --2024-02-05 01:01:01.1111111
SELECT DATEADD(weekday, 31, @datetime2);    --2024-02-01 01:01:01.1111111
SELECT DATEADD(hour, 23, @datetime2);       --2024-01-02 00:01:01.1111111
SELECT DATEADD(minute, 59, @datetime2);     --2024-01-01 02:00:01.1111111
SELECT DATEADD(second, 59, @datetime2);     --2024-01-01 01:02:00.1111111
SELECT DATEADD(millisecond, 1, @datetime2); --2024-01-01 01:01:01.1121111

C. Menggunakan ekspresi sebagai argumen untuk parameter angka dan tanggal

Contoh ini menggunakan berbagai jenis ekspresi sebagai argumen untuk parameter angka dan tanggal. Contohnya menggunakan database AdventureWorks.

Tentukan kolom sebagai tanggal

Contoh ini menambahkan 2 (dua) hari ke setiap nilai dalam OrderDate kolom, untuk mendapatkan kolom baru bernama PromisedShipDate:

SELECT SalesOrderID,
    OrderDate,
    DATEADD(day, 2, OrderDate) AS PromisedShipDate
FROM Sales.SalesOrderHeader;

Berikut adalah kumpulan hasil parsial:

SalesOrderID OrderDate               PromisedShipDate
------------ ----------------------- -----------------------
43659        2005-07-01 00:00:00.000 2005-07-03 00:00:00.000
43660        2005-07-01 00:00:00.000 2005-07-03 00:00:00.000
43661        2005-07-01 00:00:00.000 2005-07-03 00:00:00.000
...
43702        2005-07-02 00:00:00.000 2005-07-04 00:00:00.000
43703        2005-07-02 00:00:00.000 2005-07-04 00:00:00.000
43704        2005-07-02 00:00:00.000 2005-07-04 00:00:00.000
43705        2005-07-02 00:00:00.000 2005-07-04 00:00:00.000
43706        2005-07-03 00:00:00.000 2005-07-05 00:00:00.000
...
43711        2005-07-04 00:00:00.000 2005-07-06 00:00:00.000
43712        2005-07-04 00:00:00.000 2005-07-06 00:00:00.000
...
43740        2005-07-11 00:00:00.000 2005-07-13 00:00:00.000
43741        2005-07-12 00:00:00.000 2005-07-14 00:00:00.000

Tentukan variabel yang ditentukan pengguna sebagai angka dan tanggal

Contoh ini menentukan variabel yang ditentukan pengguna sebagai argumen untuk angka dan tanggal:

DECLARE @days INT = 365,
    @datetime DATETIME = '2000-01-01 01:01:01.111'; /* 2000 was a leap year */;

SELECT DATEADD(day, @days, @datetime);

Berikut adalah hasil yang ditetapkan.

2000-12-31 01:01:01.110

Tentukan fungsi sistem skalar sebagai tanggal

Contoh ini menentukan SYSDATETIME untuk tanggal. Nilai pasti yang dikembalikan tergantung pada hari dan waktu pelaksanaan pernyataan:

SELECT DATEADD(month, 1, SYSDATETIME());

Berikut adalah hasil yang ditetapkan.

2024-04-25 14:29:59.6727944

Tentukan subkueri skalar dan fungsi skalar sebagai angka dan tanggal

Contoh ini menggunakan subkueri skalar, MAX(ModifiedDate), sebagai argumen untuk angka dan tanggal. (SELECT TOP 1 BusinessEntityID FROM Person.Person) berfungsi sebagai argumen buatan untuk parameter angka, untuk memperlihatkan cara memilih argumen angka dari daftar nilai.

SELECT DATEADD(month,
    (SELECT TOP 1 BusinessEntityID FROM Person.Person),
    (SELECT MAX(ModifiedDate) FROM Person.Person));

Tentukan ekspresi numerik dan fungsi sistem skalar sebagai angka dan tanggal

Contoh ini menggunakan ekspresi numerik (), operator unary (-), operator aritmatika (/), dan fungsi sistem skalar (SYSDATETIME) sebagai argumen untuk angka dan tanggal.-(10 / 2)

SELECT DATEADD(month, -(10 / 2), SYSDATETIME());

Tentukan fungsi peringkat sebagai angka

Contoh ini menggunakan fungsi peringkat sebagai argumen untuk angka.

SELECT p.FirstName,
    p.LastName,
    DATEADD(day, ROW_NUMBER() OVER (ORDER BY a.PostalCode), SYSDATETIME()) AS 'Row Number'
FROM Sales.SalesPerson AS s
INNER JOIN Person.Person AS p
    ON s.BusinessEntityID = p.BusinessEntityID
INNER JOIN Person.Address AS a
    ON a.AddressID = p.BusinessEntityID
WHERE TerritoryID IS NOT NULL
    AND SalesYTD <> 0;

Tentukan fungsi jendela agregat sebagai angka

Contoh ini menggunakan fungsi jendela agregat sebagai argumen untuk angka.

SELECT SalesOrderID,
    ProductID,
    OrderQty,
    DATEADD(day, SUM(OrderQty) OVER (PARTITION BY SalesOrderID), SYSDATETIME()) AS 'Total'
FROM Sales.SalesOrderDetail
WHERE SalesOrderID IN (43659, 43664);
GO