Возврат соответствующей даты из нескольких таблиц, включая дополнительную информацию о таблице - PullRequest
2 голосов
/ 23 декабря 2011

Это продолжается с запроса, который ранее был решен с помощью stackoverflow ( Возвращение ближайшей даты к дате в другой таблице ), однако теперь я хочу развить ее немного дальше.

У меня есть следующий SQL:

SELECT *
FROM (SELECT O_ASSESSMENTS.ASM_SUBJECT_ID as "P Number", 
             O_ASSESSMENTS.ASM_ID as "Assessment ID", 
             O_ASSESSMENTS.ASM_START_DATE as "Assessment Start",  
             O_ASSESSMENTS.ASM_END_DATE as "Assessment End", 
             O_SERVICE_EVENTS.SEV_ID as "Event ID", 
             O_SERVICE_EVENTS.SEV_ACTUAL_DATE as "Event Start", 
             O_SERVICE_EVENTS.SEV_OUTCOME_DATE as "Event End",
             ROUND(O_ASSESSMENTS.ASM_START_DATE -O_SERVICE_EVENTS.SEV_ACTUAL_DATE,0) as "Likely",
             row_number() over(PARTITION BY  O_ASSESSMENTS.ASM_ID                                    
                               ORDER BY abs(O_ASSESSMENTS.ASM_START_DATE -  O_SERVICE_EVENTS.SEV_ACTUAL_DATE))as "Row Number"            
      FROM O_ASSESSMENTS 
      JOIN O_SERVICE_EVENTS
        ON O_ASSESSMENTS.ASM_SUBJECT_ID = O_SERVICE_EVENTS.SEV_SUBJECT_ID
      Where O_SERVICE_EVENTS.SEV_CODE IN ('ICS_E3','CPINVEST') AND 
            O_ASSESSMENTS.ASM_QSA_ID  IN ('AA1329','AA521') )
WHERE "Row Number" = 1

По сути, у нас есть две таблицы - o_assessments и o_service_events, и этот SQL возвращает ближайший сервисный случай для оценки.Теперь я хочу включить в запрос дополнительную контекстную информацию, чтобы сделать ее более полезной для конечного пользователя, а именно: имя команды и имя работника.

К сожалению, команда и работник снова находятся в другой таблице (o_responsabilities) и связаны с o_assessments asm_id с res_rec_id.

Проблема в том, что я действительно не уверен, как вызвать эту таблицу в вышеупомянутый sql - так что любой совет будет действительно признателен!

Мне также было интересно, можно ли настроить существующий запрос так, чтобы он возвращал только соответствующие события, когда «вероятное» поле имело разницу в 0 (поскольку что-то большее, вероятно, не связано с этой конкретной оценкой).Я знаю, что могу добавить его в где, но если я добавлю строку

and "Likely" = 0

, он возвращает только оценки с событием, которое не выделит никаких проблем (т. Е. Оценки без соответствующих событий).

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

Редактировать:

Хорошо, следуя решению Маркаэто то, что у меня работает.

SELECT 
* 
FROM 
(SELECT 
OAS.ASM_SUBJECT_ID as "P Number",
OAS.ASM_ID as "Assessment ID",
OAS.ASM_START_DATE as "Assessment Start", 
OAS.ASM_END_DATE as "Assessment End",
OAS.ASM_AUTH_DATETIME as "Authorisation Date",
nvl(olm_bo.get_ref_desc(OAS.ASM_OUTCOME,'ASM_OUTCOME'),'') as "Outcome",
nvl(olm_bo.get_org_name(ORE.RES_PARTY_OUN_ID),'') as "Team",
nvl(olm_bo.get_per_name(ORE.RES_PARTY_ID),'') as "Worker",
OSE.SEV_ID as "Event ID",
OSE.SEV_ACTUAL_DATE as "Event Start",
OSE.SEV_OUTCOME_DATE as "Event End",
ROUND(OAS.ASM_START_DATE -OSE.SEV_ACTUAL_DATE,0) as "Likely",
row_number() over(PARTITION BY  OAS.ASM_ID                   
ORDER BY 
abs(OAS.ASM_START_DATE -  OSE.SEV_ACTUAL_DATE))as "Row Number"
FROM O_ASSESSMENTS OAS      
INNER JOIN O_RESPONSIBILITIES ORE ON OAS.ASM_ID = ORE.RES_REC_ID
AND ORE.RES_PARTY_OUN_ID = 'TEAM'
LEFT JOIN O_SERVICE_EVENTS OSE ON OAS.ASM_SUBJECT_ID = OSE.SEV_SUBJECT_ID 
AND            
OSE.SEV_CODE IN ('EVENT') 
AND             
ROUND(OAS.ASM_START_DATE - OSE.SEV_ACTUAL_DATE,0) >= -7
AND
ROUND(OAS.ASM_START_DATE - OSE.SEV_ACTUAL_DATE,0) <= 7
Where OAS.ASM_QSA_ID  IN ('ACODE')
AND
nvl(olm_bo.get_ref_desc(OAS.ASM_OUTCOME,'ASM_OUTCOME'),'') <> 'Abandon' ) WHERE "Row Number" = 1 

Ответы [ 3 ]

1 голос
/ 23 декабря 2011

Попробуйте:

SELECT *
FROM (SELECT OAS.ASM_SUBJECT_ID as "P Number", 
             OAS.ASM_ID as "Assessment ID", 
             OAS.ASM_START_DATE as "Assessment Start",  
             OAS.ASM_END_DATE as "Assessment End", 
             ORE.TEAM,
             ORE.WORKER,
             OSE.SEV_ID as "Event ID", 
             OSE.SEV_ACTUAL_DATE as "Event Start", 
             OSE.SEV_OUTCOME_DATE as "Event End",
             ROUND(OAS.ASM_START_DATE -OSE.SEV_ACTUAL_DATE,0) as "Likely",
             row_number() over(PARTITION BY  OAS.ASM_ID                                    
                               ORDER BY abs(OAS.ASM_START_DATE -  OSE.SEV_ACTUAL_DATE))as "Row Number"            
      FROM O_ASSESSMENTS OAS
      LEFT JOIN O_RESPONSIBILITIES ORE
        ON OAS.ASM_ID = ORE.RES_REC_ID
      LEFT JOIN O_SERVICE_EVENTS OSE
        ON OAS.ASM_SUBJECT_ID = OSE.SEV_SUBJECT_ID AND
           OSE.SEV_CODE IN ('ICS_E3','CPINVEST') AND 
           ROUND(OAS.ASM_START_DATE - OSE.SEV_ACTUAL_DATE,0) = 0
      Where OAS.ASM_QSA_ID  IN ('AA1329','AA521') )
WHERE "Row Number" = 1

Обратите внимание, что это предполагает, что RES_REC_ID является уникальным идентификатором для O_RESPONSIBILITIES.

1 голос
/ 23 декабря 2011

Начало нового - правильный курс действий;редактирование вопроса для «добавления области» не является хорошей практикой.Это относится к разделу «Добавление области действия», поэтому новый вопрос был правильным подходом.

SELECT
ID, "Assessment ID", 
"Assessment Start", "Assessment End", "Event ID", 
"Event Start", "Event End", Likely, Team_name, Worker_name
FROM
  (SELECT 
  O_ASSESSMENTS.ASM_SUBJECT_ID as "ID", 
  O_ASSESSMENTS.ASM_ID as "Assessment ID", 
  O_ASSESSMENTS.ASM_START_DATE as "Assessment Start",  
  O_ASSESSMENTS.ASM_END_DATE as "Assessment End", 
  O_SERVICE_EVENTS.SEV_ID as "Event ID", 
  O_SERVICE_EVENTS.SEV_ACTUAL_DATE as "Event Start", 
  O_SERVICE_EVENTS.SEV_OUTCOME_DATE as "Event End",
  ROUND(O_ASSESSMENTS.ASM_START_DATE -O_SERVICE_EVENTS.SEV_ACTUAL_DATE,0) as "Likely",
  row_number() over(PARTITION BY  O_ASSESSMENTS.ASM_ID                                    
    ORDER BY abs(O_ASSESSMENTS.ASM_START_DATE -  
    O_SERVICE_EVENTS.SEV_ACTUAL_DATE))    as "Row    Number",
  RES.TEAM_NAME,
  RES.WORKER_NAME
  FROM O_ASSESSMENTS 
  INNER JOIN  O_SERVICE_EVENTS
    ON O_ASSESSMENTS.ASM_SUBJECT_ID = O_SERVICE_EVENTS.SEV_SUBJECT_ID
  INNER JOIN O_Responsibilities res 
    ON O_Assessments.ASM_ID = res.res_rec_ID
  WHERE O_SERVICE_EVENTS.SEV_CODE IN ('ICS_E3','CPINVEST')
    AND O_ASSESSMENTS.ASM_QSA_ID IN ('AA1329','AA521') )  InnerTable
WHERE "Row Number" = 1 and (Likely = 0 or LIKELY is null)

Все, что я здесь сделал, было

  1. Добавьте критерии присоединения к внутреннему оператору выбора
  2. Включены столбцы, которые вы запрашивали, хотя имена не были предоставлены, поэтому я предположил, что TEAM_NAME и WORKER_NAME в операторах выбора INNER и OUTER
  3. Исключил AND после объединения перед символом where в комментарии кисходное сообщение
  4. Добавлен псевдоним к имени таблицы во внутреннем select, если в какой-то момент необходимы соединения с внешней таблицей.
  5. Добавлен (вероятный = 0 или вероятный равен нулю) к внешнему выражению where
  6. Немного переформатирован SQL, чтобы его можно было прочитать здесь.

на 5 выше, этоможет быть не совсем правильно, я не совсем понимаю ваш комментарий об оценках, не имеющих даты обслуживания.В этом случае соединение между оценками и сервисами ДОЛЖНО быть левым, вместо ВНУТРЕННЕГО, если вы хотите ВСЕ оценки и связанные сервисы, если они существуют.В настоящее время вы получаете только те оценки, которые имеют связанные услуги.Если вам нужны все оценки, могут потребоваться другие изменения.

Итак ...

  FROM O_ASSESSMENTS 
  INNER JOIN  O_SERVICE_EVENTS
    ON O_ASSESSMENTS.ASM_SUBJECT_ID = O_SERVICE_EVENTS.SEV_SUBJECT_ID

станет (изменился только ВНУТРЕННИЙ ЛЕВ)

  FROM O_ASSESSMENTS 
  LEFT JOIN  O_SERVICE_EVENTS
    ON O_ASSESSMENTS.ASM_SUBJECT_ID = O_SERVICE_EVENTS.SEV_SUBJECT_ID

и предполагается, что оценка всегда имеет запись об ответственности, если неттам также потребуется ЛЕВОЕ объединение.

Наконец, нужно подумать о том, какой результат вы хотите получить ПОЛНОСТЬЮ, когда SEV_Actual_Date равен нулю.Какое значение, вероятно, должно иметь?

0 голосов
/ 23 декабря 2011

Вы можете просто присоединить o_responsibilities к встроенному представлению по соответствующим идентификаторам и затем включить его столбцы в запрос.

Имейте в виду, что вам нужно поместить бит where likely = 0 во внешний запрос (с критерием номера строки), а не во встроенное представление, поскольку likely является псевдонимом. Если вы хотите выделить оценки без событий, вы должны выполнить left join, а также добавить условие, что sev_id is null.

Нечто подобное должно сработать:

select  *
from   (select    o_assessments.asm_subject_id                      as "P Number", 
                  o_assessments.asm_id                              as "Assessment ID", 
                  o_assessments.asm_start_date                      as "Assessment Start",  
                  o_assessments.asm_end_date                        as "Assessment End", 
                  o_service_events.sev_id                           as "Event Id", 
                  o_service_events.sev_actual_date                  as "Event Start", 
                  o_service_events.sev_outcome_date                 as "Event End",
                  o_responsibilities.[WHATEVER]                     as "Team/Worker Stuff",
                  round(o_assessments.asm_start_date - o_service_events.sev_actual_date,0)
                                                                    as "Likely",
                  row_number() over (partition by o_assessments.asm_id                                    
                                     order by     abs(o_assessments.asm_start_date - o_service_events.sev_actual_date))
                                                                    as rn
        from      o_assessments 
        left join o_service_events
        on        o_service_events.sev_subject_id                    = o_assessments.asm_subject_id
        left join o_responsibilities
        on        o_responsibilities.res_rec_id                      = o_assessments.asm_id
        where     o_service_events.sev_code                         in ('ICS_E3','CPINVEST')
        and       o_assessments.asm_qsa_id                          in ('AA1329','AA521'))
where   rn = 1
and    (likely = 0 or sev_id is null);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...