2013-02-16 2 views
0

У меня есть две родительские таблицы, как показано нижеst_distance с помощью родителей геометрии

CREATE TABLE GISD.CUSTOMERS 
(CUSTOMER_ID INTEGER NOT NULL, 
FIRST_NAME VARCHAR (15) NOT NULL, 
SURNAME VARCHAR (20) NOT NULL, 
DATE_OF_BIRTH DATE NOT NULL, 
HOUSE_NUMBER VARCHAR (5) NOT NULL      
POST_CODE VARCHAR(8) NOT NULL, 
STREET VARCHAR (25) NOT NULL, 
TOWN VARCHAR (25) NOT NULL 
); 

SELECT ADDGEOMETRYCOLUMN('gisd','customers', 'customers_geom', '27700','POINT',2); 

и

CREATE TABLE GISD.CINEMAS 
(CINEMA_ID INTEGER NOT NULL, 
CINEMA_NAME VARCHAR(25) NOT NULL, 
ADDRESS_NUMBER INTEGER NOT NULL, 
POST_CODE VARCHAR(8) NOT NULL, 
STREET VARCHAR (25) NOT NULL, 
TOWN VARCHAR (25) NOT NULL, 
OPENING_TIME TIME NOT NULL, 
CLOSING_TIME TIME NOT NULL 
); 

SELECT ADDGEOMETRYCOLUMN('gisd','cinemas', 'cinemas_geom', '27700','POLYGON',2); 
SELECT ADDGEOMETRYCOLUMN('gisd','cinemas', 'centroid', '27700','POINT',2); 

У меня есть ребенок, который использует внешние ключи от обеих этих таблиц, как, например:

CREATE TABLE GISD.BOOKING 
(BOOKING_ID INTEGER NOT NULL, 
CUSTOMER_ID INTEGER NOT NULL, 
CINEMA_ID INTEGER NOT NULL, 
TIME TIME NOT NULL, 
DATE DATE NOT NULL, 
FILM VARCHAR(50) NOT NULL, 
BOOKING_METHOD VARCHAR (15) NOT NULL, 
BOOKING_FEE NUMERIC NOT NULL -- Numeric is suggested by postgresql.org for currency 
TICKET_PRICE NUMERIC NOT NULL 
); 

есть способ, который позволит мне взять уникальный идентификатор бронирования и вернуться к геометрии клиента и географии кино metry для вычисления ST_Distance? Я предполагаю, что какой-то вложенный запрос может это сделать, но мне не повезло?

веселит

UPDATE (с комментариями)

Я попытался следующий код:

SELECT (ST_DISTANCE(
    (SELECT centroid 
     FROM GISD.CINEMAS 
     INNER JOIN GISD.BOOKING ON CINEMAS.CINEMA_ID=BOOKING.CINEMA_ID 
    ),(
     SELECT customers_geom 
     FROM GISD.CUSTOMERS 
     INNER JOIN GISD.BOOKING ON CUSTOMERS.CUSTOMER_ID=BOOKING.CUSTOMER_ID 
    ) 
    )) 

но получаю сообщение об ошибке сказав «более чем один ряд, возвращаемый подзапроса используется в качестве выражения «Есть идеи, как обойти это? Я в идеале хочу, чтобы он возвращал расстояние для каждого бронирования. ID

+2

1) Добавить FK: ССЫЛКИ клиентов (id) в customer_id в таблице бронирования. 2) аналогично для cinema_id 3) объединить DATE + время в одно временное поле (гораздо проще обрабатывать и сравнивать). 4) Вам просто нужно выбрать «select ... from join B ON ... join c ON ...» type запроса. – wildplasser

+0

Просто google 'SQL JOIN' и прочитайте документы. –

+0

Спасибо, ребята. Ты указал мне в правильном направлении! Я попытался следующий код SELECT (ST_DISTANCE ((SELECT центроид ОТ GISD.CINEMAS INNER JOIN GISD.BOOKING ПО CINEMAS.CINEMA_ID = BOOKING.CINEMA_ID), (SELECT customers_geom ОТ GISD.CUSTOMERS INNER JOIN GISD.BOOKING на клиентов .CUSTOMER_ID = BOOKING.CUSTOMER_ID))) , но получите сообщение об ошибке «более одной строки, возвращенной подзапросом, используемым как выражение» Любые идеи, как обойти это? Я в идеале хочу, чтобы он возвращал расстояние для каждого идентификатора бронирования – user2076033

ответ

1

Исправленная схема с первичными/внешними ключами и именами LOWERCASED.

DROP SCHEMA tmp CASCADE; 
CREATE SCHEMA tmp; 
SET search_path=tmp; 

CREATE TABLE tmp.customers 
     (customer_id INTEGER NOT NULL PRIMARY KEY 
     , first_name VARCHAR (15) NOT NULL 
     , surname VARCHAR (20) NOT NULL 
     , date_of_birth DATE NOT NULL 
     , house_number VARCHAR (5) NOT NULL 
     , post_code VARCHAR(8) NOT NULL 
     , street VARCHAR (25) NOT NULL 
     , town VARCHAR (25) NOT NULL 
     ); 

SELECT addgeometrycolumn('tmp','customers', 'customers_geom', '27700','POINT',2); 

-- and 

CREATE TABLE tmp.cinemas 
     (cinema_id INTEGER NOT NULL PRIMARY KEY 
     , cinema_name VARCHAR(25) NOT NULL 
     , address_number INTEGER NOT NULL 
     , post_code VARCHAR(8) NOT NULL 
     , street VARCHAR (25) NOT NULL 
     , town VARCHAR (25) NOT NULL 
     , opening_time TIME NOT NULL 
     , closing_time TIME NOT NULL 
     ); 

SELECT addgeometrycolumn('tmp','cinemas', 'cinemas_geom', '27700','POLYGON',2); 
SELECT addgeometrycolumn('tmp','cinemas', 'centroid', '27700','POINT',2); 

-- I have a junction table between these tables as such: 

CREATE TABLE tmp.BOOKING 
     (booking_id INTEGER NOT NULL PRIMARY KEY 
     , customer_id INTEGER NOT NULL REFERENCES tmp.customers (customet_id) 
     , cinema_id INTEGER NOT NULL REFERENCES tmp.cinemas (cinema_id) 
     , zdatetime timestamp NOT NULL 
     , film VARCHAR(50) NOT NULL 
     , booking_method VARCHAR (15) NOT NULL 
     , booking_fee NUMERIC NOT NULL 
     , ticket_price NUMERIC NOT NULL 
     ); 

Скелет для 3-полосная присоединиться:

SELECT bo.booking_id, bo.zdatetime, bo.film 
     , ci.cinemas_geom 
     , ci.centroid 
     , cu.customers_geom 
FROM booking bo 
JOIN customers cu ON cu.customer_id = bo.customer_id 
JOIN cinemas ci ON ci.cinema_id = bo.cinema_id 
     ; 

Теперь, просто добавьте вызов функции, используя результаты из skeletton в качестве аргументов функции (я не то, что свободно в ГИС, это только пример для демонстрации синтаксиса):

SELECT bo.booking_id, bo.zdatetime, bo.film 
     , st_distance(ci.centroid , cu.customers_geom) AS the_distance 
FROM booking bo 
JOIN customers cu ON cu.customer_id = bo.customer_id 
JOIN cinemas ci ON ci.cinema_id = bo.cinema_id 
     ; 
Смежные вопросы