sql >> Database teknologi >  >> RDS >> Oracle

Oracle SQL Loop gennem datointerval

Sådan kan du få et udvalg af datoer:

 SELECT DATE'2015-01-01' + LEVEL - 1
   FROM dual
CONNECT BY DATE'2015-01-01' + LEVEL - 1 < DATE'2015-02-01';

Ovenstående vil få alle datoer i intervallet 1. januar 2015 til 31. januar 2015.

Hvad du kan gøre ved at bruge ovenstående, er at tilslutte dine start- og slutdatoer og oprette en CTE, og derefter bruge en ydre joinforbindelse på datoerne:

WITH dr AS (
    SELECT DATE'2015-01-01' + LEVEL - 1 AS transaction_date
      FROM dual
   CONNECT BY DATE'2015-01-01' + LEVEL - 1 < DATE'2015-01-04'
)
SELECT V.VISIT_ID, dr.transaction_date
     , P.NAME_LAST, ETT.ENC_TRANS_TYPE_NAME
...
       ENCOUNTER_TRANSACTION ET RIGHT JOIN dr
    ON ET.ENCOUNTER_TRANSACTION_DATE = dr.transaction_date

OPDATERING Jeg havde lidt tid, og jeg tror, ​​jeg kan se, hvordan ovenstående kan integreres i din forespørgsel. Jeg har ikke rigtig eksempeldata til en SQL Fiddle (det har du i hvert fald mange tabeller til). Det er her, du kan starte, dette bør få alle de relevante besøg plus hver dato i intervallet af datoer på besøget (forudsat at intet besøg overstiger 30 dage - juster det i overensstemmelse hermed):

WITH dr AS (
    SELECT LEVEL AS dd FROM dual
   CONNECT BY LEVEL <= 30 -- I'm assuming a max date range of 30; increase as you see fit
)
SELECT v.visit_id, v.start_date - 1 + dr.dd AS encounter_transaction_date
     , p.name_last, ett.enc_trans_type_name
  FROM visit v CROSS JOIN dr
 WHERE v.start_date - 1 + dr.dd < TRUNC(v.end_date) + 1
   AND v.institution_id = 1
   AND v.end_date IS NOT NULL
   AND v.voided_yn = 'N'
   AND v.care_setting_code = 'I'
   AND v.patient_team_id IN (16,17,18)
   AND v.start_date >= TRUNC(ADD_MONTHS(CURRENT_DATE, -1), 'MONTH')
   AND v.end_date < TRUNC(CURRENT_DATE, 'MONTH');

Så synes jeg, at dine ydre joins burde være LEFT JOINs derfra (i hvert fald, hvis jeg forstår det rigtigt, hvilket jeg måske ikke må:

WITH dr AS (
    SELECT LEVEL AS dd FROM dual
   CONNECT BY LEVEL <= 30 -- I'm assuming a max date range of 30; increase as you see fit
)
SELECT v.visit_id, v.start_date - 1 + dr.dd AS encounter_transaction_date
  FROM visit v CROSS JOIN dr
  LEFT JOIN encounter_transaction et
    ON v.visit_id = et.visit_id
   AND v.institution_id = et.institution_id
   AND TRUNC(v.start_date - 1 + dr.dd) = et.encounter_transaction_date
  LEFT JOIN encounter_transaction_type ETT
    ON et.encounter_type_id = ett.encounter_transaction_type_id
  LEFT JOIN local_provider lp
    ON et.ordering_provider_id = lp.local_provider_id
  LEFT JOIN person_identifier i
    ON i.identifier = lp.provider_number
   AND i.identifier_sys_id = lp.provider_number_sys_id
   AND i.identifier IN (
       '1234', --Smith
       '4321' --Jones ** you had an extra comma here!
)
  LEFT JOIN person p
    ON p.person_id = i.person_id
 WHERE v.start_date - 1 + dr.dd < TRUNC(v.end_date) + 1
   AND v.institution_id = 1
   AND v.end_date IS NOT NULL
   AND v.voided_yn = 'N'
   AND v.care_setting_code = 'I'
   AND v.patient_team_id IN (16,17,18)
   AND v.start_date >= TRUNC(ADD_MONTHS(CURRENT_DATE, -1), 'MONTH')
   AND v.start_date < TRUNC(CURRENT_DATE, 'MONTH');



  1. databaseforbindelse virker ikke i jar, men virker i eclipse

  2. skriv en forespørgsel, der gælder for en hel db i stedet for en tabel

  3. Den angivne cast er ikke gyldig, når DataTable udfyldes fra OracleDataAdapter.Fill()

  4. Problem med PHP og Mysql UTF-8 (Special Character)