0

Assuming I have the following PostgreSQL query:

SELECT (
 SELECT SUM (t.customers) 
 FILTER (
 WHERE id = 1
 AND date 
 BETWEEN %(start)s AND %(stop)s
 ) + 
 SELECT SUM (t.employees) 
 FILTER (
 WHERE id = 1
 AND date 
 BETWEEN %(start)s AND %(stop)s
 )
FROM table t;

and I want to duplicate the result so that the returned table has three columns. Should I copy the subquery three times, separated by a comma? That seems a messy way of doing it and not optimal as the query would be conducted three times(?). I'd rather I give an alias, let's say eaters, to the query and write a new query returning the alias three times:

-- The SELECT above AS eaters and then:
SELECT (
 SELECT * FROM eaters, SELECT * FROM eaters, SELECT * FROM eaters
);

That should be ok also performance wise, I guess. Is there some other neat effective way of duplicating the result n times inside the main query?

I query school restaurant data divided into three parts: total result, result without drinks and just the drinks. The number of eaters (= customers + employees) will be presented in each result table and is always the same for all three columns. Obviously there is the same number of customers, no matter which part is considered. So I need the same value three times. I could of course replace the following values with text, 'same as total' etc. and it would be understood. But I'd prefer learning about this and presenting the numbers.

EDIT: using CTEs I'd come up with this kind of query:

WITH customers AS (
 SELECT SUM (customers)
 FROM table
 WHERE id = 1
 AND date 
 BETWEEN %(start)s AND %(stop)s
), employees AS (
 SELECT SUM (employees)
 FROM table
 WHERE id = 1
 AND date 
 BETWEEN %(start)s AND %(stop)s
);
SELECT (
 (SELECT * FROM customers) + (SELECT * FROM employees)
) AS eaters;
SELECT (
 SELECT * FROM eaters, SELECT * FROM eaters, SELECT * FROM eaters
);
asked Dec 6, 2023 at 11:18
2
  • 1
    Maybe it's more reasonable to filter and aggregate the table in CTE then build needed sums in outer query? Commented Dec 6, 2023 at 11:34
  • @Akina please see the edited question. It doesn't seem to be a better way in any sense. Not worse, either. Commented Dec 6, 2023 at 11:41

1 Answer 1

1

I might not understand the problem, but:

SELECT my_sum, my_sum, my_sum
FROM (
 SELECT SUM(t.customers) FILTER (
 WHERE id = 1
 AND date BETWEEN %(start)s AND %(stop)s
 ) + SUM(t.employees) FILTER (
 WHERE id = 1
 AND date BETWEEN %(start)s AND %(stop)s
 ) as my_sum
 FROM t
) AS tt;

If the filters are always the same, it may be better to move them to a where clause:

SELECT my_sum, my_sum, my_sum
FROM (
 SELECT SUM(t.customers) + SUM(t.employees) as my_sum
 FROM t
 WHERE id = 1
 AND date BETWEEN %(start)s AND %(stop)s
) AS tt;

Fiddle

Paul White
95.3k30 gold badges439 silver badges689 bronze badges
answered Dec 6, 2023 at 11:46
3
  • This looks better, I didn't know that it's possible to "multiselect" like that. And thanks for the latter example, I'm new to SQL and didn't see that possibility. Commented Dec 6, 2023 at 13:15
  • 1
    @jvkloc, SQL is closed in the sense that the result of a select query is a derived table. I.e. you can select from a query just fine. Commented Dec 6, 2023 at 14:15
  • 1
    While Postgres allows duplicate identifiers in the outer query level, it's typically instrumental to assign unique column aliases. Like: SELECT my_sum AS eaters1, my_sum AS eaters2, my_sum AS eaters3 FROM ... Commented Dec 6, 2023 at 19:58

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.