sascha@164: BEGIN; sascha@164: ingo@2347: CREATE SEQUENCE UNITS_ID_SEQ; ingo@2347: ingo@2347: CREATE TABLE units ( ingo@2347: id int PRIMARY KEY NOT NULL, ingo@2347: name VARCHAR(32) NOT NULL UNIQUE ingo@2347: ); ingo@2347: sascha@164: -- Gewaesser sascha@168: CREATE SEQUENCE RIVERS_ID_SEQ; sascha@168: sascha@164: CREATE TABLE rivers ( sascha@3946: id int PRIMARY KEY NOT NULL, tom@5893: official_number int8, sascha@3946: name VARCHAR(256) NOT NULL UNIQUE, sascha@3946: km_up BOOLEAN NOT NULL DEFAULT true, sascha@3946: wst_unit_id int NOT NULL REFERENCES units(id) sascha@164: ); sascha@164: sascha@164: -- Bruecke, Haefen, etc. sascha@170: CREATE SEQUENCE ATTRIBUTES_ID_SEQ; sascha@170: sascha@164: CREATE TABLE attributes ( sascha@164: id int PRIMARY KEY NOT NULL, sascha@168: value VARCHAR(256) NOT NULL UNIQUE sascha@164: ); sascha@164: sascha@164: -- segments from/to at a river sascha@170: CREATE SEQUENCE RANGES_ID_SEQ; sascha@170: sascha@164: CREATE TABLE ranges ( sascha@164: id int PRIMARY KEY NOT NULL, tom@4991: river_id int NOT NULL REFERENCES rivers(id) ON DELETE CASCADE, sascha@168: a NUMERIC NOT NULL, sascha@164: b NUMERIC, sascha@164: UNIQUE (river_id, a, b) sascha@164: ); tom@5297: sascha@164: sascha@164: -- Lage 'links', 'rechts', etc. sascha@170: CREATE SEQUENCE POSITIONS_ID_SEQ; sascha@170: sascha@164: CREATE TABLE positions ( sascha@164: id int PRIMARY KEY NOT NULL, sascha@168: value VARCHAR(256) NOT NULL UNIQUE sascha@164: ); sascha@164: sascha@758: -- Kante 'oben', 'unten' sascha@758: CREATE SEQUENCE EDGES_ID_SEQ; sascha@758: sascha@758: CREATE TABLE edges ( sascha@758: id int PRIMARY KEY NOT NULL, sascha@758: top NUMERIC, sascha@758: bottom NUMERIC sascha@758: ); sascha@758: sascha@763: -- Types of annotatations (Hafen, Bruecke, Zufluss, ...) sascha@763: CREATE SEQUENCE ANNOTATION_TYPES_ID_SEQ; sascha@763: sascha@763: CREATE TABLE annotation_types ( sascha@763: id int PRIMARY KEY NOT NULL, sascha@763: name VARCHAR(256) NOT NULL UNIQUE sascha@763: ); sascha@763: sascha@164: -- Some object (eg. Hafen) at a segment of river sascha@164: -- plus its position. sascha@170: CREATE SEQUENCE ANNOTATIONS_ID_SEQ; sascha@170: sascha@164: CREATE TABLE annotations ( sascha@164: id int PRIMARY KEY NOT NULL, tom@5783: range_id int NOT NULL REFERENCES ranges(id) ON DELETE CASCADE, tom@5783: attribute_id int NOT NULL REFERENCES attributes(id), sascha@758: position_id int REFERENCES positions(id), sascha@763: edge_id int REFERENCES edges(id), sascha@763: type_id int REFERENCES annotation_types(id) sascha@164: ); sascha@164: sascha@164: -- Pegel sascha@170: CREATE SEQUENCE GAUGES_ID_SEQ; sascha@170: sascha@164: CREATE TABLE gauges ( sascha@2371: id int PRIMARY KEY NOT NULL, sascha@2371: name VARCHAR(256) NOT NULL, tom@5207: -- remove river id here because range_id references river already tom@4991: river_id int NOT NULL REFERENCES rivers(id) ON DELETE CASCADE, tom@5207: station NUMERIC NOT NULL, sascha@2371: aeo NUMERIC NOT NULL, tom@5894: official_number int8, sascha@164: sascha@164: -- Pegelnullpunkt sascha@168: datum NUMERIC NOT NULL, sascha@164: -- Streckengueltigkeit tom@5207: range_id int NOT NULL REFERENCES ranges (id) ON DELETE CASCADE, sascha@164: sascha@167: UNIQUE (name, river_id), tom@5894: UNIQUE (official_number, river_id), sascha@194: UNIQUE (river_id, station) sascha@164: ); sascha@164: sascha@164: -- Type of a Hauptwert 'W', 'Q', 'D', etc. sascha@170: CREATE SEQUENCE MAIN_VALUE_TYPES_ID_SEQ; sascha@170: sascha@164: CREATE TABLE main_value_types ( sascha@168: id int PRIMARY KEY NOT NULL, sascha@168: name VARCHAR(256) NOT NULL UNIQUE sascha@164: ); sascha@164: sascha@164: -- Named type of a Hauptwert (eg. HQ100) sascha@170: CREATE SEQUENCE NAMED_MAIN_VALUES_ID_SEQ; sascha@170: sascha@164: CREATE TABLE named_main_values ( sascha@168: id int PRIMARY KEY NOT NULL, tom@5915: name VARCHAR(256) NOT NULL, tom@5684: type_id int NOT NULL REFERENCES main_value_types(id) sascha@164: ); sascha@164: sascha@164: -- Table for time intervals sascha@170: CREATE SEQUENCE TIME_INTERVALS_ID_SEQ; sascha@170: sascha@164: CREATE TABLE time_intervals ( sascha@164: id int PRIMARY KEY NOT NULL, sascha@168: start_time TIMESTAMP NOT NULL, sascha@164: stop_time TIMESTAMP, sascha@164: CHECK (start_time <= stop_time) sascha@164: ); tom@5298: sascha@164: sascha@164: -- Stammdaten sascha@170: CREATE SEQUENCE MAIN_VALUES_ID_SEQ; sascha@170: sascha@164: CREATE TABLE main_values ( sascha@168: id int PRIMARY KEY NOT NULL, tom@4991: gauge_id int NOT NULL REFERENCES gauges(id) ON DELETE CASCADE, sascha@168: named_value_id int NOT NULL REFERENCES named_main_values(id), sascha@168: value NUMERIC NOT NULL, sascha@164: sascha@164: time_interval_id int REFERENCES time_intervals(id), sascha@164: sascha@164: -- TODO: better checks sascha@164: UNIQUE (gauge_id, named_value_id, time_interval_id) sascha@164: ); sascha@164: sascha@164: -- Abflusstafeln sascha@170: CREATE SEQUENCE DISCHARGE_TABLES_ID_SEQ; sascha@170: sascha@167: CREATE TABLE discharge_tables ( sascha@164: id int PRIMARY KEY NOT NULL, tom@4991: gauge_id int NOT NULL REFERENCES gauges(id) ON DELETE CASCADE, sascha@493: description VARCHAR(256) NOT NULL, teichmann@4776: bfg_id VARCHAR(50), sascha@470: kind int NOT NULL DEFAULT 0, tom@5883: time_interval_id int REFERENCES time_intervals(id), tom@5923: UNIQUE(gauge_id, bfg_id, kind) sascha@164: ); sascha@164: sascha@164: -- Values of the Abflusstafeln sascha@170: CREATE SEQUENCE DISCHARGE_TABLE_VALUES_ID_SEQ; sascha@170: sascha@164: CREATE TABLE discharge_table_values ( sascha@168: id int PRIMARY KEY NOT NULL, tom@4991: table_id int NOT NULL REFERENCES discharge_tables(id) ON DELETE CASCADE, sascha@168: q NUMERIC NOT NULL, sascha@168: w NUMERIC NOT NULL, sascha@164: sascha@164: UNIQUE (table_id, q, w) sascha@164: ); sascha@164: sascha@164: -- WST files tom@5202: --lookup table for wst kinds tom@5202: CREATE TABLE wst_kinds ( tom@5202: id int PRIMARY KEY NOT NULL, tom@5202: kind VARCHAR(64) NOT NULL tom@5202: ); tom@5202: INSERT INTO wst_kinds (id, kind) VALUES (0, 'basedata'); tom@5202: INSERT INTO wst_kinds (id, kind) VALUES (1, 'basedata_additionals_marks'); tom@5202: INSERT INTO wst_kinds (id, kind) VALUES (2, 'basedata_fixations_wst'); tom@5202: INSERT INTO wst_kinds (id, kind) VALUES (3, 'basedata_officials'); tom@5202: INSERT INTO wst_kinds (id, kind) VALUES (4, 'basedata_heightmarks-points-relative_points'); tom@5202: INSERT INTO wst_kinds (id, kind) VALUES (5, 'basedata_flood-protections_relative_points'); tom@5202: INSERT INTO wst_kinds (id, kind) VALUES (6, 'morpho_waterlevel-differences'); tom@5202: INSERT INTO wst_kinds (id, kind) VALUES (7, 'morpho_waterlevels'); tom@5202: tom@5202: sascha@171: CREATE SEQUENCE WSTS_ID_SEQ; sascha@170: sascha@171: CREATE TABLE wsts ( sascha@168: id int PRIMARY KEY NOT NULL, tom@4991: river_id int NOT NULL REFERENCES rivers(id) ON DELETE CASCADE, sascha@168: description VARCHAR(256) NOT NULL, tom@5202: kind int NOT NULL REFERENCES wst_kinds(id) DEFAULT 0, sascha@164: -- TODO: more meta infos sascha@164: UNIQUE (river_id, description) sascha@164: ); sascha@164: sascha@164: -- columns of WST files sascha@171: CREATE SEQUENCE WST_COLUMNS_ID_SEQ; sascha@170: sascha@171: CREATE TABLE wst_columns ( sascha@168: id int PRIMARY KEY NOT NULL, tom@4991: wst_id int NOT NULL REFERENCES wsts(id) ON DELETE CASCADE, sascha@168: name VARCHAR(256) NOT NULL, sascha@174: description VARCHAR(256), sascha@471: position int NOT NULL DEFAULT 0, sascha@164: tom@6011: time_interval_id int REFERENCES time_intervals(id), sascha@164: sascha@471: UNIQUE (wst_id, name), sascha@471: UNIQUE (wst_id, position) sascha@164: ); sascha@164: sascha@164: -- w values in WST file column sascha@170: CREATE SEQUENCE WST_COLUMN_VALUES_ID_SEQ; sascha@170: sascha@164: CREATE TABLE wst_column_values ( sascha@168: id int PRIMARY KEY NOT NULL, tom@4991: wst_column_id int NOT NULL REFERENCES wst_columns(id) ON DELETE CASCADE, sascha@168: position NUMERIC NOT NULL, sascha@168: w NUMERIC NOT NULL, sascha@164: sascha@164: UNIQUE (position, wst_column_id), sascha@164: UNIQUE (position, wst_column_id, w) sascha@164: ); sascha@164: sascha@164: -- bind q values to range sascha@170: CREATE SEQUENCE WST_Q_RANGES_ID_SEQ; sascha@170: sascha@164: CREATE TABLE wst_q_ranges ( sascha@168: id int PRIMARY KEY NOT NULL, tom@4991: range_id int NOT NULL REFERENCES ranges(id) ON DELETE CASCADE, sascha@168: q NUMERIC NOT NULL sascha@164: ); sascha@164: sascha@164: -- bind q ranges to wst columns sascha@170: CREATE SEQUENCE WST_COLUMN_Q_RANGES_ID_SEQ; sascha@170: sascha@164: CREATE TABLE wst_column_q_ranges ( sascha@164: id int PRIMARY KEY NOT NULL, tom@4991: wst_column_id int NOT NULL REFERENCES wst_columns(id) ON DELETE CASCADE, tom@4991: wst_q_range_id int NOT NULL REFERENCES wst_q_ranges(id) ON DELETE CASCADE, sascha@164: sascha@164: UNIQUE (wst_column_id, wst_q_range_id) sascha@164: ); sascha@164: sascha@476: CREATE VIEW wst_value_table AS tom@6078: SELECT tom@6078: wcv.position AS position, tom@6078: w, tom@6078: q, tom@6078: wc.position AS column_pos, tom@6078: w.id AS wst_id tom@6078: FROM wsts w tom@6078: JOIN wst_columns wc tom@6078: ON wc.wst_id=w.id tom@6078: JOIN wst_column_q_ranges wcqr tom@6078: ON wcqr.wst_column_id=wc.id tom@6078: JOIN wst_q_ranges wqr tom@6078: ON wcqr.wst_q_range_id=wqr.id tom@6078: JOIN ranges r tom@6078: ON wqr.range_id=r.id tom@6078: JOIN wst_column_values wcv tom@6078: ON wcv.wst_column_id=wc.id AND wcv.position between r.a and r.b; sascha@476: ORDER BY wcv.position ASC, tom@6078: wc.position DESC; sascha@476: sascha@754: -- view to select the w values of a WST sascha@754: CREATE VIEW wst_w_values AS sascha@754: SELECT wcv."position" AS km, sascha@754: wcv.w AS w, sascha@754: wc."position" AS column_pos, sascha@754: w.id AS wst_id sascha@754: FROM wst_column_values wcv sascha@754: JOIN wst_columns wc ON wcv.wst_column_id = wc.id sascha@754: JOIN wsts w ON wc.wst_id = w.id sascha@754: ORDER BY wcv."position", wc."position"; sascha@754: sascha@755: -- view to select the q values of a WST sascha@755: CREATE VIEW wst_q_values AS sascha@755: SELECT wc.position AS column_pos, sascha@755: wqr.q AS q, sascha@755: r.a AS a, sascha@755: r.b AS b, sascha@755: wc.wst_id AS wst_id sascha@755: FROM wst_column_q_ranges wcqr sascha@755: JOIN wst_q_ranges wqr ON wcqr.wst_q_range_id = wqr.id sascha@755: JOIN ranges r ON wqr.range_id = r.id sascha@755: JOIN wst_columns wc ON wcqr.wst_column_id = wc.id sascha@755: ORDER BY wc.position, wcqr.wst_column_id, r.a; sascha@755: sascha@1192: -- data for the cross-sections sascha@1192: sascha@1192: CREATE SEQUENCE CROSS_SECTIONS_ID_SEQ; sascha@1192: sascha@1192: CREATE TABLE cross_sections ( sascha@1192: id int PRIMARY KEY NOT NULL, tom@6030: river_id int NOT NULL REFERENCES rivers(id) ON DELETE CASCADE, tom@6030: time_interval_id int REFERENCES time_intervals(id), sascha@1202: description VARCHAR(256) sascha@1192: ); sascha@1192: sascha@1205: CREATE SEQUENCE CROSS_SECTION_LINES_ID_SEQ; sascha@1203: sascha@1203: CREATE TABLE cross_section_lines ( sascha@1203: id int PRIMARY KEY NOT NULL, sascha@1203: km NUMERIC NOT NULL, tom@4991: cross_section_id int NOT NULL REFERENCES cross_sections(id) ON DELETE CASCADE, sascha@1203: UNIQUE (km, cross_section_id) sascha@1203: ); sascha@1203: sascha@1192: CREATE SEQUENCE CROSS_SECTION_POINTS_ID_SEQ; sascha@1192: sascha@1192: CREATE TABLE cross_section_points ( sascha@1203: id int PRIMARY KEY NOT NULL, tom@4991: cross_section_line_id int NOT NULL REFERENCES cross_section_lines(id) ON DELETE CASCADE, sascha@1203: col_pos int NOT NULL, sascha@1203: x NUMERIC NOT NULL, sascha@1203: y NUMERIC NOT NULL, sascha@1203: UNIQUE (cross_section_line_id, col_pos) sascha@1192: ); sascha@1192: sascha@3796: -- Indices for faster access of the points sascha@3796: CREATE INDEX cross_section_lines_km_idx sascha@3796: ON cross_section_lines(km); sascha@3796: CREATE INDEX cross_section_points_line_idx sascha@3796: ON cross_section_points(cross_section_line_id); sascha@3796: sascha@1209: -- Hydraulische Kenngroessen sascha@1209: sascha@1209: CREATE SEQUENCE HYKS_ID_SEQ; sascha@1209: sascha@1209: CREATE TABLE hyks ( sascha@1209: id int PRIMARY KEY NOT NULL, tom@4991: river_id int NOT NULL REFERENCES rivers(id) ON DELETE CASCADE, sascha@1209: description VARCHAR(256) NOT NULL sascha@1209: ); sascha@1209: sascha@1209: CREATE SEQUENCE HYK_ENTRIES_ID_SEQ; sascha@1209: sascha@1209: CREATE TABLE hyk_entries ( sascha@1212: id int PRIMARY KEY NOT NULL, tom@4991: hyk_id int NOT NULL REFERENCES hyks(id) ON DELETE CASCADE, sascha@1212: km NUMERIC NOT NULL, sascha@1217: measure TIMESTAMP, sascha@1209: UNIQUE (hyk_id, km) sascha@1209: ); sascha@1209: sascha@1209: CREATE SEQUENCE HYK_FORMATIONS_ID_SEQ; sascha@1209: sascha@1209: CREATE TABLE hyk_formations ( sascha@1209: id int PRIMARY KEY NOT NULL, sascha@1209: formation_num int NOT NULL DEFAULT 0, tom@4991: hyk_entry_id int NOT NULL REFERENCES hyk_entries(id) ON DELETE CASCADE, sascha@1209: top NUMERIC NOT NULL, sascha@1209: bottom NUMERIC NOT NULL, sascha@1214: distance_vl NUMERIC NOT NULL, sascha@1214: distance_hf NUMERIC NOT NULL, sascha@1214: distance_vr NUMERIC NOT NULL, sascha@1209: UNIQUE (hyk_entry_id, formation_num) sascha@1209: ); sascha@1209: sascha@1209: CREATE SEQUENCE HYK_FLOW_ZONE_TYPES_ID_SEQ; sascha@1209: sascha@1209: CREATE TABLE hyk_flow_zone_types ( sascha@1209: id int PRIMARY KEY NOT NULL, sascha@1209: name VARCHAR(50) NOT NULL UNIQUE, sascha@1209: description VARCHAR(256) sascha@1209: ); sascha@1209: sascha@1209: CREATE SEQUENCE HYK_FLOW_ZONES_ID_SEQ; sascha@1209: sascha@1209: CREATE TABLE hyk_flow_zones ( sascha@1209: id int PRIMARY KEY NOT NULL, tom@4991: formation_id int NOT NULL REFERENCES hyk_formations(id) ON DELETE CASCADE, sascha@1209: type_id int NOT NULL REFERENCES hyk_flow_zone_types(id), sascha@1209: a NUMERIC NOT NULL, sascha@1209: b NUMERIC NOT NULL, sascha@1209: CHECK (a <= b) sascha@1209: ); sascha@1209: sascha@3335: CREATE VIEW official_lines sascha@3335: AS sascha@3335: SELECT w.river_id AS river_id, sascha@3335: w.id AS wst_id, sascha@3335: wc.id AS wst_column_id, felix@3470: wc.name AS name, felix@3470: wc.position AS wst_column_pos sascha@3335: FROM wsts w sascha@3335: JOIN wst_columns wc sascha@3335: ON wc.wst_id = w.id sascha@3335: WHERE w.kind = 3; sascha@3335: sascha@3335: CREATE VIEW q_main_values sascha@3335: AS sascha@3335: SELECT riv.id AS river_id, sascha@3335: g.id AS gauge_id, sascha@3335: g.name AS gauge_name, sascha@3335: r.a AS a, sascha@3335: r.b AS b, sascha@3335: REGEXP_REPLACE( sascha@3335: nmv.name, E'[:space:]*\\(.*\\)[:space:]*', '') AS name, sascha@3335: CAST(mv.value AS NUMERIC(38, 2)) AS value sascha@3335: FROM main_values mv sascha@3335: JOIN named_main_values nmv sascha@3335: ON mv.named_value_id = nmv.id sascha@3335: JOIN main_value_types mvt sascha@3335: ON nmv.type_id = mvt.id sascha@3335: JOIN gauges g sascha@3335: ON mv.gauge_id = g.id sascha@3335: JOIN ranges r sascha@3335: ON g.range_id = r.id sascha@3335: JOIN rivers riv sascha@3335: ON g.river_id = riv.id sascha@3335: WHERE mvt.name = 'Q' sascha@3335: ORDER BY g.id, CAST(mv.value AS NUMERIC(38,2)); sascha@3335: sascha@3335: CREATE VIEW official_q_values sascha@3335: AS sascha@3335: SELECT ol.river_id AS river_id, sascha@3335: wst_id, sascha@3335: wst_column_id, sascha@3335: gauge_id, sascha@3335: gauge_name, sascha@3335: a, sascha@3335: b, sascha@3335: ol.name, felix@3470: value, felix@3470: wst_column_pos sascha@3335: FROM official_lines ol sascha@3335: JOIN q_main_values qmv sascha@3335: ON ol.river_id = qmv.river_id sascha@3335: AND ol.name = qmv.name; sascha@3335: teichmann@4651: CREATE VIEW wst_ranges teichmann@4651: AS teichmann@4651: SELECT wc.id AS wst_column_id, teichmann@4651: wc.wst_id AS wst_id, teichmann@4651: Min(wcv.position) AS a, teichmann@4651: Max(wcv.position) AS b teichmann@4651: FROM wst_columns wc teichmann@4651: JOIN wst_column_values wcv teichmann@4651: ON wc.id = wcv.wst_column_id teichmann@4651: GROUP BY wc.id, teichmann@4651: wc.wst_id; teichmann@4651: sascha@164: COMMIT;