Mengkueri data dalam tabel temporal versi sistem
Berlaku untuk: SQL Server 2016 (13.x) dan Azure SQL Database Azure SQL Managed Instance yang lebih baru
Saat Anda ingin mendapatkan status data terbaru (saat ini) dalam tabel temporal, Anda bisa mengkueri dengan cara yang sama seperti Anda mengkueri tabel non-temporal. PERIOD
Jika kolom tidak disembunyikan, nilainya muncul dalam SELECT *
kueri. Jika Anda menentukan PERIOD
kolom sebagai HIDDEN
, nilainya tidak muncul dalam SELECT *
kueri. PERIOD
Saat kolom disembunyikan, Anda harus mereferensikan PERIOD
kolom secara khusus dalam SELECT
klausul untuk mengembalikan nilai untuk kolom ini.
Untuk melakukan semua jenis analisis berbasis waktu, gunakan klausul baru FOR SYSTEM_TIME
dengan empat subklaus khusus temporal untuk mengkueri data di seluruh tabel saat ini dan riwayat. Untuk informasi selengkapnya tentang klausul ini, lihat Tabel temporal dan klausa FROM ditambah JOIN, APPLY, PIVOT
AS OF <date_time>
FROM <start_date_time> TO <end_date_time>
BETWEEN <start_date_time> AND <end_date_time>
CONTAINED IN (<start_date_time>, <end_date_time>)
ALL
FOR SYSTEM_TIME
dapat ditentukan secara independen untuk setiap tabel dalam kueri. Ini dapat digunakan di dalam ekspresi tabel umum, fungsi bernilai tabel, dan prosedur tersimpan. Saat menggunakan alias tabel dengan tabel temporal, FOR SYSTEM_TIME
klausa harus disertakan antara nama tabel temporal dan alias (lihat Kueri untuk waktu tertentu menggunakan AS OF
contoh kedua subklasifikasi ).
Kueri untuk waktu tertentu menggunakan AS OF
subklaus
AS OF
Gunakan subklasul saat Anda perlu membangun ulang status data seperti pada waktu tertentu di masa lalu. Anda dapat menyusun ulang data dengan presisi jenis datetime2 yang ditentukan dalam PERIOD
definisi kolom.
AS OF
Subklaus dapat digunakan dengan literal konstanta atau dengan variabel, sehingga Anda dapat menentukan kondisi waktu secara dinamis. Nilai yang disediakan ditafsirkan sebagai waktu UTC.
Contoh pertama ini mengembalikan status dbo. Tabel departemen AS OF
tanggal tertentu di masa lalu.
-- State of entire table AS OF specific date in the past
SELECT [DeptID],
[DeptName],
[ValidFrom],
[ValidTo]
FROM [dbo].[Department]
FOR SYSTEM_TIME AS OF '2021-09-01 T10:00:00.7230011';
Contoh kedua ini membandingkan nilai antara dua titik waktu untuk subset baris.
DECLARE @ADayAgo DATETIME2;
SET @ADayAgo = DATEADD(DAY, -1, SYSUTCDATETIME());
-- Comparison between two points in time for subset of rows
SELECT D_1_Ago.[DeptID],
D.[DeptID],
D_1_Ago.[DeptName],
D.[DeptName],
D_1_Ago.[ValidFrom],
D.[ValidFrom],
D_1_Ago.[ValidTo],
D.[ValidTo]
FROM [dbo].[Department]
FOR SYSTEM_TIME AS OF @ADayAgo AS D_1_Ago
INNER JOIN [Department] AS D
ON D_1_Ago.[DeptID] = [D].[DeptID]
AND D_1_Ago.[DeptID] BETWEEN 1 AND 5;
Menggunakan tampilan dengan AS OF
subklaus dalam kueri temporal
Menggunakan tampilan berguna dalam skenario ketika analisis waktu titik waktu yang kompleks diperlukan. Contoh umum adalah membuat laporan bisnis hari ini dengan nilai untuk bulan sebelumnya.
Biasanya, pelanggan memiliki model database yang dinormalisasi, yang melibatkan banyak tabel dengan hubungan kunci asing. Mencari tahu bagaimana data dari model yang dinormalisasi melihat titik di masa lalu dapat menjadi tantangan, karena semua tabel berubah secara independen pada irama mereka sendiri.
Dalam hal ini, opsi terbaik adalah membuat tampilan dan menerapkan AS OF
subklasul ke seluruh tampilan. Menggunakan pendekatan ini memungkinkan Anda memisahkan pemodelan lapisan akses data dari analisis waktu titik waktu, karena SQL Server menerapkan klausul AS OF
secara transparan ke semua tabel temporal yang berpartisipasi dalam definisi tampilan. Selain itu, Anda dapat menggabungkan temporal dengan tabel non-temporal dalam tampilan yang sama dan AS OF
hanya diterapkan pada tabel temporal. Jika tampilan tidak mereferensikan setidaknya satu tabel temporal, menerapkan klausa kueri temporal ke dalamnya gagal dengan kesalahan.
Kode sampel berikut membuat tampilan yang menggabungkan tiga tabel temporal: Department
, , CompanyLocation
dan LocationDepartments
:
CREATE VIEW [dbo].[vw_GetOrgChart]
AS
SELECT [CompanyLocation].LocID,
[CompanyLocation].LocName,
[CompanyLocation].City,
[Department].DeptID,
[Department].DeptName
FROM [dbo].[CompanyLocation]
LEFT JOIN [dbo].[LocationDepartments]
ON [CompanyLocation].LocID = LocationDepartments.LocID
LEFT JOIN [dbo].[Department]
ON LocationDepartments.DeptID = [Department].DeptID;
GO
Anda bisa mengkueri tampilan menggunakan AS OF
subklaus dan literal datetime2 :
/* Querying view AS OF */
SELECT * FROM [vw_GetOrgChart]
FOR SYSTEM_TIME AS OF '2021-09-01 T10:00:00.7230011';
Kueri untuk perubahan pada baris tertentu dari waktu ke waktu
Subklaus temporal , BETWEEN ... AND
dan CONTAINED IN
berguna ketika Anda perlu mendapatkan semua perubahan historis FROM ... TO
untuk baris tertentu dalam tabel saat ini (juga dikenal sebagai audit data).
Dua subklasifikasi pertama mengembalikan versi baris yang tumpang tindih dengan periode tertentu (yaitu, yang dimulai sebelum periode yang diberikan dan berakhir setelahnya), sementara CONTAINED IN
hanya mengembalikan yang ada dalam batas periode yang ditentukan.
Jika Anda mencari versi baris non-saat ini saja, Anda harus mengkueri tabel riwayat secara langsung, untuk performa kueri terbaik. Gunakan ALL
saat Anda perlu mengkueri data saat ini dan historis tanpa batasan apa pun.
/* Query using BETWEEN...AND sub-clause*/
SELECT [DeptID],
[DeptName],
[ValidFrom],
[ValidTo],
IIF(YEAR(ValidTo) = 9999, 1, 0) AS IsActual
FROM [dbo].[Department]
FOR SYSTEM_TIME BETWEEN '2021-01-01' AND '2021-12-31'
WHERE DeptId = 1
ORDER BY ValidFrom DESC;
/* Query using CONTAINED IN sub-clause */
SELECT [DeptID],
[DeptName],
[ValidFrom],
[ValidTo]
FROM [dbo].[Department]
FOR SYSTEM_TIME CONTAINED IN ('2021-04-01', '2021-09-25')
WHERE DeptId = 1
ORDER BY ValidFrom DESC;
/* Query using ALL sub-clause */
SELECT [DeptID],
[DeptName],
[ValidFrom],
[ValidTo],
IIF(YEAR(ValidTo) = 9999, 1, 0) AS IsActual
FROM [dbo].[Department]
FOR SYSTEM_TIME ALL
ORDER BY [DeptID],
[ValidFrom] DESC;