0

I have a table like this

books
|---------------------|------------------|------------------|------------------|
|         book        |       source     |    store_price   |  bookstore_price |
|---------------------|------------------|------------------|------------------|
|        Batman       |       store      |       10.5       |        9.5       |
|---------------------|------------------|------------------|------------------|
|       Superman      |     bookstore    |       null       |         9        |
|---------------------|------------------|------------------|------------------|

I need to select books and sum prices and my query so far looks like this

SELECT
    book,
    SUM(
        CASE
            WHEN source = 'store' then store_price
            WHEN source = 'bookstore' then bookstore_price
        END
    ) AS price
FROM books
GROUP BY 1
;

Is it possible to somehow optimize SUM select for ex. select source||'_price' from books;?

Thank you in advance!

3
  • Change your design. There is no need for 2 price columns. Use 1 column price and then the column source is enough to distinguish what kind of price you have. Commented Mar 24, 2020 at 7:46
  • this is short version of a complex table view i have and i can not change it ;) Commented Mar 24, 2020 at 7:49
  • 1
    with t(book, source, store_price, bookstore_price) as (values('Batman'::text, 'store'::text, 10.5, 9.5), ('Superman', 'bookstore', null, 9)) select *, (to_jsonb(t)->(source||'_price'))::numeric from t; But it is really bad design IMO. Commented Mar 24, 2020 at 8:46

2 Answers 2

1

I"m not 100% sure if this helps, but you can unpivot the data and aggregate:

select b.book, sum(v.price)
from books b join lateral
     (values ('store', store_price),
             ('bookstore', bookstore_price)
     ) v(source, price)
     on v.source = b.source
group by b.book;
Sign up to request clarification or add additional context in comments.

Comments

0

You can use the COALESCE function:

SELECT
    book,
    source,
    SUM(
        COALESCE(store_price,bookstore_price,0)
    ) AS price
FROM books
GROUP BY 1
;

2 Comments

it will work only if one column is filled, but won't if both
Yes - if you have more than 1 non-NULL price then you have bad data in the database and will have to either use CASE statements to overcome that or to cleanup the data and put a constraint so that only one of the prices is non-NULL.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.