简体   繁体   中英

Join tables with names matching a pattern

I am trying to write a query where I want to join all tables with names that match a specific pattern.

Example

I have 12 tables (one for each month) containing daily temperature values and I want to return temperatures across any range of dates (eg 1/26/2014-3/5/2014).

My tables are named with the pattern temperature_m01 , temperature_m02 , ..., temperature_m12 .

I can simply join all tables together by writing out each join explicitly but I want a cleaner way to imply that I want to join all tables temperature_m* .

Once I know how to do this I figure I can add some additional constrains, such as only joining the tables for the months in the range I need, which might give slight improvements.


So far I am thinking that the best way to do this is use python to write the query for me, but this doesn't seem particularly clean either.

This is normally an anti-pattern, you should rather have a single table with a field that indicates the month.

You can, however, create a view to combine your 12 tables and query that as if it were all of your tables together...

CREATE VIEW temperature_all AS (
    SELECT 01 AS month_id, * FROM temperature_m01
    UNION ALL
    SELECT 02 AS month_id, * FROM temperature_m02
    UNION ALL
    SELECT 03 AS month_id, * FROM temperature_m03
    UNION ALL
    SELECT 04 AS month_id, * FROM temperature_m04
    UNION ALL
    SELECT 05 AS month_id, * FROM temperature_m05
    UNION ALL
    SELECT 06 AS month_id, * FROM temperature_m06
    UNION ALL
    SELECT 07 AS month_id, * FROM temperature_m07
    UNION ALL
    SELECT 08 AS month_id, * FROM temperature_m08
    UNION ALL
    SELECT 09 AS month_id, * FROM temperature_m09
    UNION ALL
    SELECT 10 AS month_id, * FROM temperature_m10
    UNION ALL
    SELECT 11 AS month_id, * FROM temperature_m11
    UNION ALL
    SELECT 12 AS month_id, * FROM temperature_m12
);

SELECT * FROM temperature_all WHERE your_date_field BETWEEN '2014-01-26' AND '2014-03-05';

This is similar to how partitioning works.

First, this is a bad data structure. You should have all the data in a single table, with a column representing the month.

That said, Postgres offers a couple of things that can help. One is to use a view (as Matt answers in another question).

Another is to use inheritance . So, you could create a parent table, say temperature_m , and do:

alter table temperature_m01 inherits temperature_m;

This then allows you to do:

select . . .
 from temperature_m*

However, for this to work, you'll have to put the common columns you want in temperature_m . . . and we are back to creating a single table for the data. That is really the best approach.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM