2016-07-26 2 views
-1

Полностью SQL-новичок, пытающийся преобразовать один из моих R-запросов в запрос Oracle SQL - извинения, если я получу терминологию неправильно, но я попытаюсь быть явным.Oracle Left соединяется между датами двух разных схем

Использование Oracle SQL Developer 4.0.3.16 для Windows.

Я пытаюсь объединить таблицы («VMS» и «TRIP») из двух разных схем (schA и schB) на основе диапазона дат и идентификатора разрешения. Я хочу сделать левое соединение (сохранить все строки из schA.VMS и только поле TRIP_JOIN из schB ... оставляя NA в поле TRIP_JOIN, когда даты не совпадают).

описание двух schemas.table:

describe schA.VMS 
Name    Null  Type   
----------------- -------- ----------- 
PERMIT      NUMBER(6) 
POSITION_DATETIME NOT NULL DATE   
LATITUDE  NOT NULL NUMBER(9,6) 
LONGITUDE  NOT NULL NUMBER(9,6) 


describe schB.TRIP 
Name      Null  Type   
-------------------------- -------- ------------ 
PERMIT      NOT NULL VARCHAR2(6) 
TRIP_JOIN     NOT NULL NUMBER  
TRIP_START       DATE   
TRIP_END       DATE  

Я пытался различные версии кода ниже

alter session set nls_date_format = 'mm/dd/yyyy HH24:MI' 

SELECT schA.VMS.*,TRIP_JOIN FROM schA.VMS 
    LEFT JOIN schA.VMS 
    ON schA.VMS.POSITION_DATETIME BETWEEN 
    to_date(schB.TRIP.TRIP_START) AND to_date(schB.TRIP.TRIP_END) 
    WHERE to_char(schA.VMS.PERMIT) = schB.TRIP.PERMIT 

Я получаю сообщение об ошибке. Я предполагаю, что я не могу определить, какие аспекты, но я не могу понять, какой аспект!

ORA-00904: "schB"."TRIP"."TRIP_END": invalid identifier 
00904. 00000 - "%s: invalid identifier" 
*Cause:  
*Action: 
Error at Line: 20 Column: 115 

Я попытался выяснить, как обеспечить воспроизводимый пример, но мои навыки Oracle еще не совсем там. Извиняюсь, и, надеюсь, мои ошибки достаточно очевидны без этого!

Я нашел сообщения SO для разных частей моего вопроса, но я не мог найти другого, что бы устранить пробелы.

Заранее благодарен!

+2

Ваш запрос выполняет автообъединение на 'schA.VMS' (' FROM schA.VMS' и 'LEFT JOIN schA.VMS'). Вы вообще не присоединяетесь к 'schB.TRIP', поэтому вы не можете ссылаться на эту таблицу. Проверьте свои 'from' и' join' предложения. Кроме того, вы можете значительно упростить свой запрос, используя псевдонимы таблиц. – sstan

+0

Downvotes гораздо более конструктивны, когда сопровождаются объяснением, поэтому новички, подобные мне, могут улучшить будущие вопросы. Благодаря! – Jordan

ответ

1

Вы получаете сообщение об ошибке при попытке выбрать «SCHB». «TRIP». «TRIP_END», потому что вы не присоединились к «SCHB». «Trip»

+0

Как только я исправил это, есть ли очевидная причина, по которой я не получаю значения NULL из правой таблицы? Кажется, я получаю строки, в которых они совпадают, что в моем скудном понимании является внутренним соединением вместо левого соединения. Правильно ли это? – Jordan

+0

Неправильно, и это вызвано предложением WHERE, которое вместо этого должно быть в предложении ON JOIN.Я уточню свой ответ, чтобы отразить это. – mathguy

2

Объединяя советы от ответа Луки и комментарий sstan в - Вы, вероятно, хотите что-то подобное.

У вас есть еще одна ошибка в вашем запросе, которая станет очевидной после исправления первой. t.TRIP_START и t.TRIP_END - это даты, но вы завершаете их в пределах to_date().. Это обязательно вызовет проблемы.

SELECT v.*, t.TRIP_JOIN 
FROM schA.VMS v LEFT JOIN schB.TRIP t 
    ON v.POSITION_DATETIME BETWEEN t.TRIP_START AND t.TRIP_END 
WHERE to_char(v.PERMIT) = t.PERMIT 
; 

Edited: В комментариях к другому ответу, ОП отметил, что после исправления синтаксических ошибок, запрос кажется выполнить внутреннее соединение вместо соединения слева. Это вызвано предложением WHERE; кажется, что OP означает это дополнительное условие соединения. Как условие WHERE, фильтрация выполняется ПОСЛЕ завершения соединения и отфильтровывает дополнительные строки, добавленные внешним соединением. Для того, чтобы получить желаемый результат, запрос должен быть написан так:

SELECT v.*, t.TRIP_JOIN 
FROM schA.VMS v LEFT JOIN schB.TRIP t 
    ON v.POSITION_DATETIME BETWEEN t.TRIP_START AND t.TRIP_END 
AND to_char(v.PERMIT) = t.PERMIT      ---- not WHERE 
; 
+0

Спасибо - я уже принял ответ Люка, который, кажется, работает, но я ценю более подробный ответ (как и другие, я уверен) (+ 1). Я удалил to_date(), и он не * появился *, чтобы изменить результат, однако он на порядок быстрее без to_date(), так что это мило! – Jordan

+1

Это улучшение производительности показывает, что у вас есть индексы на TRIP_START и TRIP_END (как вы, вероятно, должны). Объединение их в вызовы функций предотвращает использование этих индексов; правильно пишите условия и используются индексы! Рад, что это помогло. – mathguy

Смежные вопросы