Depending on database provider, you can use
Common Table Expressions[
^], which can be used in recursive mode.
SQL Server:
WITH common_table_expression (Transact-SQL) - SQL Server | Microsoft Docs[
^]
SQL Server Common Table Expressions (CTE)[
^]
For example:
;WITH CTE AS
(
SELECT 1 AS Lvl, CheckNo, CAST(OpenDate AS DATETIME) + CAST(OpenTime AS DATETIME) AS OT,
DATEADD(MI, 30, CAST(OpenDate AS DATETIME) + CAST(OpenTime AS DATETIME)) AS CT,
CAST(OpenDate AS DATETIME) + CAST(CloseTime AS DATETIME) AS OCT
FROM InitialData
UNION ALL
SELECT Lvl + 1 AS Lvl, CheckNo, CT AS OT, DATEADD(mi, 30, CT), OCT
FROM CTE
WHERE DATEADD(mi, 30, OT) < OCT
)
SELECT Lvl, CheckNo, OT AS OpenTime, CT AS CloseTime
FROM CTE
ORDER BY CheckNo, Lvl
Sample output:
Lvl CheckNo OpenTime CloseTime
1 25484 2022-04-26 17:34:00.000 2022-04-26 18:04:00.000
1 25484 2022-04-26 18:06:00.000 2022-04-26 18:36:00.000
2 25484 2022-04-26 18:36:00.000 2022-04-26 19:06:00.000
3 25484 2022-04-26 19:06:00.000 2022-04-26 19:36:00.000
4 25484 2022-04-26 19:36:00.000 2022-04-26 20:06:00.000
5 25484 2022-04-26 20:06:00.000 2022-04-26 20:36:00.000
6 25484 2022-04-26 20:36:00.000 2022-04-26 21:06:00.000
7 25484 2022-04-26 21:06:00.000 2022-04-26 21:36:00.000
SQL Server 2019 | db<>fiddle[
^]
Good luck!