'Join tables either left or right based upon existence of data

currently I'm working on joining multiple tables together with Postgres, I've currently written a script that joins the tables from A to B, however I want to join the tables from B to A if there's no data in A, but there's data in B. Let me give a brief description of my table structure:

planned_passtimes

create table "PassTimes".planned_passtimes
(
    "DataOwnerCode"         varchar(255) not null,
    "LocalServiceLevelCode" varchar(255) not null,
    "LinePlanningNumber"    varchar(255),
    "JourneyNumber"         integer,
    "UserStopCode"          varchar(255),
    "TargetArrivalTime"     varchar(255),
    "TargetDepartureTime"   varchar(255),
    "IsTimingStop"          boolean,
    "VehicleJourneyType"    varchar(255),
    ... And about 20 other not-important columns.
)

passtimes

create table "PassTimes".passtimes
(
    "DataOwnerCode"         varchar(255) not null,
    "LocalServiceLevelCode" varchar(255) not null,
    "LinePlanningNumber"    varchar(255),
    "JourneyNumber"         integer,
    "UserStopCode"          varchar(255),
    "TargetArrivalTime"     varchar(255),
    "TargetDepartureTime"   varchar(255),
    "IsTimingStop"          boolean,
    "VehicleJourneyType"    varchar(255),
    ... And about 60 other not-important columns.
)


service_validity

create table "PassTimes".service_validity
(
    "DataOwnerCode"         varchar(255) not null,
    "LocalServiceLevelCode" varchar(255) not null,
    "OperationDate"         varchar(255) not null,
);

Sometimes the "primary" data is to be found in planned_passtimes while in other cases, the primary data is to be found in passtimes.

To join the tables I currently have the following query:

SELECT DISTINCT
        planned_passtimes."TargetArrivalTime",
        passtimes."ExpectedArrivalTime",
        planned_passtimes."TargetDepartureTime",
        passtimes."ExpectedDepartureTime",
        planned_passtimes."DataOwnerCode",
        planned_passtimes."LinePlanningNumber",
        planned_passtimes."JourneyNumber"
      FROM
        "PassTimes".service_validity
        JOIN "PassTimes".planned_passtimes ON service_validity."LocalServiceLevelCode" = planned_passtimes."LocalServiceLevelCode"
        LEFT JOIN "PassTimes".passtimes ON (
          planned_passtimes."UserStopCode" = passtimes."UserStopCode" AND
          planned_passtimes."JourneyNumber" = passtimes."JourneyNumber" AND
          planned_passtimes."LinePlanningNumber" = passtimes."LinePlanningNumber"
        )
      WHERE
        service_validity."OperationDate" = '2022-04-08'
      AND planned_passtimes."TargetArrivalTime" > '13:00:00'
      AND planned_passtimes."TargetArrivalTime" < '15:00:00'
      AND planned_passtimes."JourneyStopType" != 'LAST'
      ORDER BY planned_passtimes."TargetArrivalTime" DESC LIMIT 10;

The "pivot" table in this case is service_validity which includes unique validity codes based upon the current date for both tables. Rows in each table can be matches with the unique combination of UserStopCode, JourneyNumber and LinePlanningNumber.

This query currently joins passtimes to planned_passtimes, however I would like to also do the reverse, so join planned_passtimes to passtimes (notably when there is no data found for the first join), as all fetched columns are ambigious between the two tables I figured there must be a way to do this.

I've read about cross-join but I'm not sure it is the way to solve this question? Maybe what I'm trying to do isn't possible at all, that is also fine!

Would it maybe be better to run two queries seperately and join them back in my NodeJS back-end?

Much thanks, Tristan



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source