Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
Относится к: SQL Server 2016 (13.x) и более поздние версии
База данных SQL Azure
Управляемый экземпляр SQL Azure
SQL Database в Microsoft Fabric
Чтобы получить последнее (текущее) состояние данных во временной таблице, запросите её так же, как к невременной таблице. Если столбцы PERIOD не скрыты, их значения отображаются в запросе SELECT *. Если указать PERIOD столбцы как HIDDEN, их значения не отображаются в SELECT * запросе. Когда столбцы PERIOD скрыты, ссылайтесь на них конкретно в SELECT предложении, чтобы вернуть их значения.
Для проведения анализа на основе времени используйте FOR SYSTEM_TIME предложение с четырьмя временно-специфическими подпредложениями для запроса данных между текущими и историческими таблицами. Дополнительные сведения об этих предложениях см. в темпоральных таблицах и предложении FROM плюс 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 отдельно для каждой таблицы в запросе. Используйте его в общих выражениях таблиц, функциях с таблицьными значениями и сохранённых процедурах. Когда вы используете псевдоним таблицы с темпоральной таблицей, укажите предложение FOR SYSTEM_TIME между именем темпоральной таблицы и её псевдонимом (см. второй пример в разделе «Запрос для определённого времени с использованием вложенного предложения AS OF»).
Запрос о конкретном времени с использованием подчиненного предложения AS OF
Используйте подзапрос AS OF, чтобы восстановить состояние данных таким, каким оно было в любой конкретный момент в прошлом. Вы можете восстановить данные с точностью типа datetime2, который вы указали в определениях столбцов PERIOD.
Используйте AS OF подпредложение с постоянными литералами или переменными, чтобы динамически задать временное условие. Указанные вами значения интерпретируются как UTC-время.
Этот первый пример возвращает состояние dbo.Department таблицы AS OF на определённую дату в прошлом.
-- 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';
Во втором примере сравниваются значения в интервале между двумя моментами времени для подмножества строк.
DECLARE @ADayAgo AS 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;
Используйте представления с подзапросами AS OF в темпоральных запросах
Представления полезны, когда требуется сложный анализ данных на определённый момент времени. Распространённый пример — создание бизнес-отчета сегодня с значениями за предыдущий месяц.
Как правило, у клиентов имеется нормализованная модель базы данных, которая включает в себя множество таблиц со связями по внешнему ключу. Выяснить, как данные из этой нормализированной модели выглядели в определённый момент прошлого, бывает сложно, потому что все таблицы меняются независимо по своей частоте.
В этом случае лучше всего создать представление и применить пункт AS OF ко всему представлению. Этот подход разделяет моделирование слоя доступа к данным и анализ на определённый момент времени, поскольку SQL Server прозрачно применяет предложение AS OF ко всем временным таблицам, участвующим в определении представления. Кроме того, можно объединить темпоральные таблицы с нетемпоральными таблицами в одном представлении, и AS OF применяется только к темпоральным. Если представление не ссылается хотя бы на одну темпоральную таблицу, применение темпоральных запросов к нему завершается ошибкой.
В следующем примере кода создается представление, которое объединяет три темпоральные таблицы: Department, CompanyLocationи LocationDepartments:
CREATE VIEW [dbo].[vw_GetOrgChart]
AS
SELECT [CompanyLocation].LocID,
[CompanyLocation].LocName,
[CompanyLocation].City,
[Department].DeptID,
[Department].DeptName
FROM [dbo].[CompanyLocation]
LEFT OUTER JOIN [dbo].[LocationDepartments]
ON [CompanyLocation].LocID = LocationDepartments.LocID
LEFT OUTER JOIN [dbo].[Department]
ON LocationDepartments.DeptID = [Department].DeptID;
GO
Вы можете выполнить запрос для представления, используя AS OF подзапрос и литерал datetime2.
/* Query view AS OF */
SELECT *
FROM [vw_GetOrgChart] FOR SYSTEM_TIME
AS OF '2021-09-01 T10:00:00.7230011';
Запрос изменений в определенных строках со временем
Временные подзапросы FROM ... TO, BETWEEN ... AND и CONTAINED IN полезны, когда нужно получить все исторические изменения по конкретной строке в текущей таблице (это также называется аудитом данных).
Первые два подусловия возвращают версии строк, которые перекрываются с указанным периодом (то есть те, которые начались до данного периода и закончились после него), в то время как CONTAINED IN возвращает только те, которые существовали в пределах границ указанного периода.
Если вы ищете только версии строк, не актуальные, задавайте запросы напрямую к таблице истории для максимальной производительности. Используйте ALL для запроса текущих и исторических данных без каких-либо ограничений.
/* 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;
Анализируйте тенденции в течение определённого временного окна
Чтобы подытожить, как выглядят данные за период, объединяйте FOR SYSTEM_TIME BETWEEN ... AND и GROUP BY агрегируйте функции. Используйте этот метод для описательной статистики и анализа тенденций. Он объединяет все версии строк, которые были активны в течение этого окна, вместо того чтобы восстанавливать состояние на один конкретный момент времени.
Следующий пример вычисляет описательные статистические данные по зарплатам сотрудников в течение определённого временного окна, сгруппированные по отделам. Он использует Employee системную версионную таблицу, определённую в временных таблицах и сценариях использования временной таблицы. Столбец AnnualSalary — это числовой показатель, хорошо подходящий для функций AVG, MIN, MAX и STDEV.
Оговорка FOR SYSTEM_TIME BETWEEN ... AND возвращает все версии строки, перекрывающие период. В результате агрегированные данные включают все значения заработной платы, действовавшие в течение этого периода. При изменении зарплаты сотрудника запрос возвращает несколько версий для этого сотрудника, и каждая версия вносит вклад в агрегаты.
DECLARE @periodStart AS DATETIME2 = '2021-01-01';
DECLARE @periodEnd AS DATETIME2 = '2021-12-31';
SELECT [Department],
AVG([AnnualSalary]) AS AvgSalary,
MIN([AnnualSalary]) AS MinSalary,
MAX([AnnualSalary]) AS MaxSalary,
STDEV([AnnualSalary]) AS SalaryStdDev,
COUNT(*) AS RowVersions
FROM [dbo].[Employee] FOR SYSTEM_TIME
BETWEEN @periodStart AND @periodEnd
GROUP BY [Department]
ORDER BY AvgSalary DESC;