sql >> Database >  >> RDS >> Oracle

Oracle SQL Loop door datumbereik

Hier ziet u hoe u een reeks datums kunt krijgen:

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

Het bovenstaande krijgt alle datums in het bereik van 1 januari 2015 tot 31 januari 2015.

Wat u zou kunnen doen, met behulp van het bovenstaande, is uw start- en einddatums in te voeren en een CTE te maken, en vervolgens een outer join op de datums te gebruiken:

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

UPDATE Ik had wat tijd en ik denk dat ik zie hoe het bovenstaande kan worden geïntegreerd in uw vraag. Ik heb niet echt voorbeeldgegevens voor een SQL Fiddle (daar heb je sowieso veel tabellen voor). Dit is waar u zou kunnen beginnen, dit zou alle juiste bezoeken moeten krijgen plus elke datum binnen het bereik van de datums van het bezoek (ervan uitgaande dat geen enkel bezoek langer duurt dan 30 dagen - pas dat dienovereenkomstig aan):

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');

Dan denk ik dat je outer joins vanaf daar LEFT JOINs moeten zijn (tenminste, als ik het goed begrijp, wat ik misschien niet:

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. mysql - zoek tussen datums waar alle datums verschijnen

  2. PostgreSQL-replicatieslots gebruiken

  3. SSIS:Oracle Meerdere rijen naar één kolomuitvoer zonder STRAGG

  4. SQL-query om alleen gegevens te retourneren als ALLE noodzakelijke kolommen aanwezig zijn en niet NULL