Modularizing SQL even if only syntactic sugar
The issue here is you need to think about data in a relational way. I do not believe this type of abstraction correctly fits into the relational model. In terms of making SQL modular, that is what stored procedures and/or functions are for. Notice how these have the same characteristics as methods do in Java. You can abstract out that way. Another way is to abstract the data that is what you care about into materialized views. By doing this you can put a regular view (see virtual function) over top of these materialized views which allow you to test the structure of the data without touching the "raw" tables.
In most databases, you can do what you want using CTEs (Common Table Expressions):
with CustomerProfile as (
getCustomerProfile
),
SummarizedCustomerTransactionHistory as (
getSummarizedCustomerTransactionHistory
),
GeographicalSummaries as (
getGeographicalSummaries
)
select <whatever>
This works for a single query. It has the advantage that you can define a CTE once, but use it multiple times. Also, I often define a CTE called const
that has constant values.
The next step is to take these constructs and create views from them. This is especially useful when sharing code among multiple modules, to ensure constant definitions. In some databases, you can put indexes on the views to "instantiate" them, further optimizing processing.
Finally, I recommend wrapping inserts/updates/deletes in stored procedures. This allows you to do have a consistent framework.
Two more comments though. First, SQL is often used for transactional or reporting systems. Often, once you get the data in the right format for the purpose, the data speaks for itself. You example might just be asking for a data mart that has three tables devoted to those three subject areas, which get populated once per week or once per day.
And, SQL is not an idea language for abstraction. With good practice, naming conventions, and indentation style, you can make it useful. I sorely miss certain things from "real" languages, such as macros, error handling (why data errors are so hard to identify and handle is beyond me), consistent methods for common functionality (can someone say group string concatenation), and some other features. That said, because it is data centric and readily parallelizable, it is more useful for me than most other languages.