How to perform a time-sequenced (temporal) LEFT OUTER JOIN
10:40 15 Oct 2025

TL;DR In the book Developing Time-Oriented Database Applications in SQL by Richard T. Snodgrass, section 6.3.1 he demonstrates how to perform a sequenced inner join on a transaction-time state table, but does not discuss how to perform a sequenced left outer join.

Initial setup

Suppose the following events occur:

  • 2025-01-01 - User 0 (John) is created. Order 0 (for User 0) is created. Order 1 (for User 1) is created.
  • 2025-01-02 - User 1 (Mary) is created.
  • 2025-01-03 - User 0 (Jon) is renamed.
  • 2025-01-04 - Order 0 is moved from User 0 (Jon) to User 1 (Mary).

The resulting transaction-time state tables are these:

Note: I have deliberately combined the history and current table, unlike the official SQL server temporal tables feature which has them separated. This is similar to querying temporal tables with FOR SYSTEM_TIME ALL when using the official temporal table feature in SQL Server 2016

Orders

Id UserId ValidFrom ValidTo
0 0 2025-01-01 2025-01-04
0 1 2025-01-04 9999-12-31
1 1 2025-01-01 9999-12-31

Users

Id Name ValidFrom ValidTo
0 John 2025-01-01 2025-01-03
0 Jon 2025-01-03 9999-12-31
1 Mary 2025-01-02 9999-12-31

DDL/DML for Copy Paste

CREATE TABLE Orders (
    Id INT,
    UserId INT ,
    ValidFrom DATE,
    ValidTo DATE,
);

INSERT INTO Orders
VALUES (0, 0, '2025-01-01', '2025-01-04'),
       (0, 1, '2025-01-04', '9999-12-31'),
       (1, 1, '2025-01-01', '9999-12-31');

CREATE TABLE Users (
    Id INT,
    Name VARCHAR(50),
    ValidFrom DATE,
    ValidTo DATE
);

INSERT INTO Users
VALUES (0, 'John', '2025-01-01', '2025-01-03'),
       (0, 'Jon', '2025-01-03', '9999-12-31'),
       (1, 'Mary', '2025-01-02', '9999-12-31');

Now, I can use the following query to get all the current orders, and the associated user name:

SELECT O.Id, U.Name 
FROM Orders O
LEFT JOIN Users U ON U.Id = O.UserId AND O.ValidTo = '9999-12-31' AND U.ValidTo = '9999-12-31'

Note: query corrected per T N's answer

Results

O.Id U.Name
0 Mary
1 Mary

Question

I want to see how the results of the above query have changed over time. What query should I write to get the results shown below?

Desired Results

O.Id U.Name ValidFrom ValidTo Note (for reference, not actually part of the query)
0 John 2025-01-01 2025-01-03 User 0 + Order 0 are created
1 NULL 2025-01-01 2025-01-02 Order 1 is created
1 Mary 2025-01-02 9999-12-31 User 1 is created
0 Jon 2025-01-03 2025-01-04 User 0 is renamed
0 Mary 2025-01-04 9999-12-31 Order 0 is moved from User 0 to User 1
sql sql-server temporal-tables temporal-database