'How to retrieve weighted average price with data split across tables

Currently, I'm getting the average price across a given timestamp range. I need to retrieve the weighted average price, but I'm unsure how to convert the current query to retrieve that. The price value should be calculated as SUM(table1.volume * table2.price) / SUM(table1.volume). A requirement I have is that if all the table1.status are either N or Y in a given time range, I still need to calculate the weighted average price, but the table1.volume value should be 0.

SELECT table1.status,
       COALESCE(table1.volume, 0),
       table2.price
FROM (SELECT status,
             SUM(volume) volume
      FROM table1
      WHERE (interval_date || ' ' || interval_time_utc)::timestamp BETWEEN '2022-05-23 13:05:00.0' AND '2022-05-23 14:00:00.0'
      GROUP BY status) table1
RIGHT JOIN (SELECT symbol,
                   AVG(price) price
            FROM table2
            WHERE (interval_date || ' ' || interval_time_utc)::timestamp BETWEEN '2022-05-23 13:05:00.0' AND '2022-05-23 14:00:00.0'
            GROUP BY symbol) table2
ON table2.symbol = CASE WHEN table1.status = 'Y' THEN 'Symbol A'
                        ELSE 'Symbol B'
                   END;

db fiddle link for example: https://dbfiddle.uk/?rdbms=postgres_14&fiddle=92fde9319c1b8e3eaefb92decc843820

My current attempt at this is the following query, but I'm not getting the result I am looking for. The weighted average price and straight average price are the same value and having the COALESCE(table1.volume, 0) in the GROUP BY clause is also not ideal.

SELECT SUM(table2.price * table1.volume) / SUM(table1.volume) weighted_avg_price,
       table1.status,
       COALESCE(table1.volume, 0) volume
FROM (SELECT status,
             volume
      FROM table1
      WHERE (interval_date || ' ' || interval_time_utc)::timestamp BETWEEN '2022-05-23 13:05:00.0' AND '2022-05-23 14:00:00.0') table1
RIGHT JOIN (SELECT symbol,
                   price
            FROM table2
            WHERE (interval_date || ' ' || interval_time_utc)::timestamp BETWEEN '2022-05-23 13:05:00.0' AND '2022-05-23 14:00:00.0') table2
ON table2.symbol = CASE WHEN table1.status = 'Y' THEN 'Symbol A'
                        ELSE 'Symbol B'
                   END
GROUP BY table1.status, COALESCE(table1.volume, 0);


Sources

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

Source: Stack Overflow

Solution Source