Skip to content
Advertisement

Postgresql – access/use joined subquery result in another joined subquery

I have a database with tables for

  • equipment we service (table e, field e_id)
  • contracts on the equipment (table c, fields c_id, e_id, c_start, c_end)
  • maintenance we have performed in the past (table m, e_id, m_id, m_date)

I am trying to build a query that will show me all equipment records, if it is currently in contract with the start/end date, and a count of any maintenance performed since the start date of the contract.

I have a subquery to get the current contract (this table is large and has a new line for each contract revision), but I can’t work out how to use the result of the contract subquery to return the maintenance visits since that date without returning multiple lines.

I would also like to be able to add this
m-subquery v1

But I’m unable to access c2.C_start from within the second subquery.

I am able to return this table by joining outside the subquery, but this returns multiple lines.
m-subquery v2

Is there a way to:

  • Get the subquery field c2.start into the m-subquery v1?
  • Aggregate the result of the m-subquery v2 without using group by (there are a lot of columns in the main select query)?
  • Do this differently?

I’ve seen lateral which I kind of think might be what I need but I have tried the keyword in front of both subqueries individually and together and it didn’t work to let me use c2.c_start inside at any point.

I am a little averse to using group by, mainly as the BI analyst at work says “slap a group by on it” when there are duplicates in reports rather than trying to understand the business process/database properly. I feel like having a group by on the main query shouldn’t be needed when I know for certain that the e table has one record per e_id, and the mess that having probably 59 out of 60 columns named in the group by would cause might make the query less maintainable.

Thanks, Sam

Advertisement

Answer

Since not all RDBMS support lateral, I would like to present you the following general solution. You can make use of CTEs (WITH queries) to help structuring the query and reuse partial results. E.g. in the following code, you can think of current_contracts as a kind of virtual table existing only during query execution.

Part 1: DDLs and test data

Part 2: the actual query

Please note that your real pre-processing logic for contracts and maintenance visits may be more complex, e.g. due to overlapping periods of active contracts per equipment.

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement