-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
2723361
commit 994d782
Showing
6 changed files
with
1,902 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,5 +18,4 @@ src/*.so | |
src/*.dll | ||
/Debug | ||
standalone/build/* | ||
sql | ||
_targets |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,375 @@ | ||
CREATE TABLE #Codesets ( | ||
codeset_id int NOT NULL, | ||
concept_id bigint NOT NULL | ||
) | ||
; | ||
|
||
INSERT INTO #Codesets (codeset_id, concept_id) | ||
SELECT 0 as codeset_id, c.concept_id FROM (select distinct I.concept_id FROM | ||
( | ||
select concept_id from @vocabulary_database_schema.CONCEPT where concept_id in (1118084) | ||
|
||
) I | ||
) C | ||
; | ||
|
||
SELECT event_id, person_id, start_date, end_date, op_start_date, op_end_date, visit_occurrence_id | ||
INTO #qualified_events | ||
FROM | ||
( | ||
select pe.event_id, pe.person_id, pe.start_date, pe.end_date, pe.op_start_date, pe.op_end_date, row_number() over (partition by pe.person_id order by pe.start_date ASC) as ordinal, cast(pe.visit_occurrence_id as bigint) as visit_occurrence_id | ||
FROM (-- Begin Primary Events | ||
select P.ordinal as event_id, P.person_id, P.start_date, P.end_date, op_start_date, op_end_date, cast(P.visit_occurrence_id as bigint) as visit_occurrence_id | ||
FROM | ||
( | ||
select E.person_id, E.start_date, E.end_date, | ||
row_number() OVER (PARTITION BY E.person_id ORDER BY E.sort_date ASC, E.event_id) ordinal, | ||
OP.observation_period_start_date as op_start_date, OP.observation_period_end_date as op_end_date, cast(E.visit_occurrence_id as bigint) as visit_occurrence_id | ||
FROM | ||
( | ||
-- Begin Drug Era Criteria | ||
select C.person_id, C.drug_era_id as event_id, C.drug_era_start_date as start_date, C.drug_era_end_date as end_date, | ||
CAST(NULL as bigint) as visit_occurrence_id,C.drug_era_start_date as sort_date | ||
from | ||
( | ||
select de.* | ||
FROM @cdm_database_schema.DRUG_ERA de | ||
where de.drug_concept_id in (SELECT concept_id from #Codesets where codeset_id = 0) | ||
) C | ||
|
||
|
||
-- End Drug Era Criteria | ||
|
||
) E | ||
JOIN @cdm_database_schema.observation_period OP on E.person_id = OP.person_id and E.start_date >= OP.observation_period_start_date and E.start_date <= op.observation_period_end_date | ||
WHERE DATEADD(day,0,OP.OBSERVATION_PERIOD_START_DATE) <= E.START_DATE AND DATEADD(day,0,E.START_DATE) <= OP.OBSERVATION_PERIOD_END_DATE | ||
) P | ||
WHERE P.ordinal = 1 | ||
-- End Primary Events | ||
) pe | ||
|
||
) QE | ||
|
||
; | ||
|
||
--- Inclusion Rule Inserts | ||
|
||
create table #inclusion_events (inclusion_rule_id bigint, | ||
person_id bigint, | ||
event_id bigint | ||
); | ||
|
||
select event_id, person_id, start_date, end_date, op_start_date, op_end_date | ||
into #included_events | ||
FROM ( | ||
SELECT event_id, person_id, start_date, end_date, op_start_date, op_end_date, row_number() over (partition by person_id order by start_date ASC) as ordinal | ||
from | ||
( | ||
select Q.event_id, Q.person_id, Q.start_date, Q.end_date, Q.op_start_date, Q.op_end_date, SUM(coalesce(POWER(cast(2 as bigint), I.inclusion_rule_id), 0)) as inclusion_rule_mask | ||
from #qualified_events Q | ||
LEFT JOIN #inclusion_events I on I.person_id = Q.person_id and I.event_id = Q.event_id | ||
GROUP BY Q.event_id, Q.person_id, Q.start_date, Q.end_date, Q.op_start_date, Q.op_end_date | ||
) MG -- matching groups | ||
{0 != 0}?{ | ||
-- the matching group with all bits set ( POWER(2,# of inclusion rules) - 1 = inclusion_rule_mask | ||
WHERE (MG.inclusion_rule_mask = POWER(cast(2 as bigint),0)-1) | ||
} | ||
) Results | ||
WHERE Results.ordinal = 1 | ||
; | ||
|
||
-- custom era strategy | ||
|
||
with ctePersons(person_id) as ( | ||
select distinct person_id from #included_events | ||
) | ||
|
||
select person_id, drug_exposure_start_date, drug_exposure_end_date | ||
INTO #drugTarget | ||
FROM ( | ||
select de.PERSON_ID, DRUG_EXPOSURE_START_DATE, COALESCE(DRUG_EXPOSURE_END_DATE, DATEADD(day,DAYS_SUPPLY,DRUG_EXPOSURE_START_DATE), DATEADD(day,1,DRUG_EXPOSURE_START_DATE)) as DRUG_EXPOSURE_END_DATE | ||
FROM @cdm_database_schema.DRUG_EXPOSURE de | ||
JOIN ctePersons p on de.person_id = p.person_id | ||
JOIN #Codesets cs on cs.codeset_id = 0 AND de.drug_concept_id = cs.concept_id | ||
|
||
UNION ALL | ||
|
||
select de.PERSON_ID, DRUG_EXPOSURE_START_DATE, COALESCE(DRUG_EXPOSURE_END_DATE, DATEADD(day,DAYS_SUPPLY,DRUG_EXPOSURE_START_DATE), DATEADD(day,1,DRUG_EXPOSURE_START_DATE)) as DRUG_EXPOSURE_END_DATE | ||
FROM @cdm_database_schema.DRUG_EXPOSURE de | ||
JOIN ctePersons p on de.person_id = p.person_id | ||
JOIN #Codesets cs on cs.codeset_id = 0 AND de.drug_source_concept_id = cs.concept_id | ||
) E | ||
; | ||
|
||
select et.event_id, et.person_id, ERAS.era_end_date as end_date | ||
INTO #strategy_ends | ||
from #included_events et | ||
JOIN | ||
( | ||
select ENDS.person_id, min(drug_exposure_start_date) as era_start_date, DATEADD(day,0, ENDS.era_end_date) as era_end_date | ||
from | ||
( | ||
select de.person_id, de.drug_exposure_start_date, MIN(e.END_DATE) as era_end_date | ||
FROM #drugTarget DE | ||
JOIN | ||
( | ||
--cteEndDates | ||
select PERSON_ID, DATEADD(day,-1 * 30,EVENT_DATE) as END_DATE -- unpad the end date by 30 | ||
FROM | ||
( | ||
select PERSON_ID, EVENT_DATE, EVENT_TYPE, | ||
MAX(START_ORDINAL) OVER (PARTITION BY PERSON_ID ORDER BY event_date, event_type, START_ORDINAL ROWS UNBOUNDED PRECEDING) AS start_ordinal, | ||
ROW_NUMBER() OVER (PARTITION BY PERSON_ID ORDER BY EVENT_DATE, EVENT_TYPE, START_ORDINAL) AS OVERALL_ORD -- this re-numbers the inner UNION so all rows are numbered ordered by the event date | ||
from | ||
( | ||
-- select the start dates, assigning a row number to each | ||
Select PERSON_ID, DRUG_EXPOSURE_START_DATE AS EVENT_DATE, 0 as EVENT_TYPE, ROW_NUMBER() OVER (PARTITION BY PERSON_ID ORDER BY DRUG_EXPOSURE_START_DATE) as START_ORDINAL | ||
from #drugTarget D | ||
|
||
UNION ALL | ||
|
||
-- add the end dates with NULL as the row number, padding the end dates by 30 to allow a grace period for overlapping ranges. | ||
select PERSON_ID, DATEADD(day,30,DRUG_EXPOSURE_END_DATE), 1 as EVENT_TYPE, NULL | ||
FROM #drugTarget D | ||
) RAWDATA | ||
) E | ||
WHERE 2 * E.START_ORDINAL - E.OVERALL_ORD = 0 | ||
) E on DE.PERSON_ID = E.PERSON_ID and E.END_DATE >= DE.DRUG_EXPOSURE_START_DATE | ||
GROUP BY de.person_id, de.drug_exposure_start_date | ||
) ENDS | ||
GROUP BY ENDS.person_id, ENDS.era_end_date | ||
) ERAS on ERAS.person_id = et.person_id | ||
WHERE et.start_date between ERAS.era_start_date and ERAS.era_end_date; | ||
|
||
TRUNCATE TABLE #drugTarget; | ||
DROP TABLE #drugTarget; | ||
|
||
|
||
-- generate cohort periods into #final_cohort | ||
select person_id, start_date, end_date | ||
INTO #cohort_rows | ||
from ( -- first_ends | ||
select F.person_id, F.start_date, F.end_date | ||
FROM ( | ||
select I.event_id, I.person_id, I.start_date, CE.end_date, row_number() over (partition by I.person_id, I.event_id order by CE.end_date) as ordinal | ||
from #included_events I | ||
join ( -- cohort_ends | ||
-- cohort exit dates | ||
-- By default, cohort exit at the event's op end date | ||
select event_id, person_id, op_end_date as end_date from #included_events | ||
UNION ALL | ||
-- End Date Strategy | ||
SELECT event_id, person_id, end_date from #strategy_ends | ||
|
||
) CE on I.event_id = CE.event_id and I.person_id = CE.person_id and CE.end_date >= I.start_date | ||
) F | ||
WHERE F.ordinal = 1 | ||
) FE; | ||
|
||
select person_id, min(start_date) as start_date, end_date | ||
into #final_cohort | ||
from ( --cteEnds | ||
SELECT | ||
c.person_id | ||
, c.start_date | ||
, MIN(ed.end_date) AS end_date | ||
FROM #cohort_rows c | ||
JOIN ( -- cteEndDates | ||
SELECT | ||
person_id | ||
, DATEADD(day,-1 * 0, event_date) as end_date | ||
FROM | ||
( | ||
SELECT | ||
person_id | ||
, event_date | ||
, event_type | ||
, SUM(event_type) OVER (PARTITION BY person_id ORDER BY event_date, event_type ROWS UNBOUNDED PRECEDING) AS interval_status | ||
FROM | ||
( | ||
SELECT | ||
person_id | ||
, start_date AS event_date | ||
, -1 AS event_type | ||
FROM #cohort_rows | ||
|
||
UNION ALL | ||
|
||
|
||
SELECT | ||
person_id | ||
, DATEADD(day,0,end_date) as end_date | ||
, 1 AS event_type | ||
FROM #cohort_rows | ||
) RAWDATA | ||
) e | ||
WHERE interval_status = 0 | ||
) ed ON c.person_id = ed.person_id AND ed.end_date >= c.start_date | ||
GROUP BY c.person_id, c.start_date | ||
) e | ||
group by person_id, end_date | ||
; | ||
|
||
DELETE FROM @target_database_schema.@target_cohort_table where cohort_definition_id = @target_cohort_id; | ||
INSERT INTO @target_database_schema.@target_cohort_table (cohort_definition_id, subject_id, cohort_start_date, cohort_end_date) | ||
select @target_cohort_id as cohort_definition_id, person_id, start_date, end_date | ||
FROM #final_cohort CO | ||
; | ||
|
||
{0 != 0}?{ | ||
-- BEGIN: Censored Stats | ||
|
||
delete from @results_database_schema.cohort_censor_stats where cohort_definition_id = @target_cohort_id; | ||
|
||
-- END: Censored Stats | ||
} | ||
{0 != 0 & 0 != 0}?{ | ||
|
||
CREATE TABLE #inclusion_rules (rule_sequence int); | ||
|
||
-- Find the event that is the 'best match' per person. | ||
-- the 'best match' is defined as the event that satisfies the most inclusion rules. | ||
-- ties are solved by choosing the event that matches the earliest inclusion rule, and then earliest. | ||
|
||
select q.person_id, q.event_id | ||
into #best_events | ||
from #qualified_events Q | ||
join ( | ||
SELECT R.person_id, R.event_id, ROW_NUMBER() OVER (PARTITION BY R.person_id ORDER BY R.rule_count DESC,R.min_rule_id ASC, R.start_date ASC) AS rank_value | ||
FROM ( | ||
SELECT Q.person_id, Q.event_id, COALESCE(COUNT(DISTINCT I.inclusion_rule_id), 0) AS rule_count, COALESCE(MIN(I.inclusion_rule_id), 0) AS min_rule_id, Q.start_date | ||
FROM #qualified_events Q | ||
LEFT JOIN #inclusion_events I ON q.person_id = i.person_id AND q.event_id = i.event_id | ||
GROUP BY Q.person_id, Q.event_id, Q.start_date | ||
) R | ||
) ranked on Q.person_id = ranked.person_id and Q.event_id = ranked.event_id | ||
WHERE ranked.rank_value = 1 | ||
; | ||
|
||
-- modes of generation: (the same tables store the results for the different modes, identified by the mode_id column) | ||
-- 0: all events | ||
-- 1: best event | ||
|
||
|
||
-- BEGIN: Inclusion Impact Analysis - event | ||
-- calculte matching group counts | ||
delete from @results_database_schema.cohort_inclusion_result where cohort_definition_id = @target_cohort_id and mode_id = 0; | ||
insert into @results_database_schema.cohort_inclusion_result (cohort_definition_id, inclusion_rule_mask, person_count, mode_id) | ||
select @target_cohort_id as cohort_definition_id, inclusion_rule_mask, count_big(*) as person_count, 0 as mode_id | ||
from | ||
( | ||
select Q.person_id, Q.event_id, CAST(SUM(coalesce(POWER(cast(2 as bigint), I.inclusion_rule_id), 0)) AS bigint) as inclusion_rule_mask | ||
from #qualified_events Q | ||
LEFT JOIN #inclusion_events I on q.person_id = i.person_id and q.event_id = i.event_id | ||
GROUP BY Q.person_id, Q.event_id | ||
) MG -- matching groups | ||
group by inclusion_rule_mask | ||
; | ||
|
||
-- calculate gain counts | ||
delete from @results_database_schema.cohort_inclusion_stats where cohort_definition_id = @target_cohort_id and mode_id = 0; | ||
insert into @results_database_schema.cohort_inclusion_stats (cohort_definition_id, rule_sequence, person_count, gain_count, person_total, mode_id) | ||
select @target_cohort_id as cohort_definition_id, ir.rule_sequence, coalesce(T.person_count, 0) as person_count, coalesce(SR.person_count, 0) gain_count, EventTotal.total, 0 as mode_id | ||
from #inclusion_rules ir | ||
left join | ||
( | ||
select i.inclusion_rule_id, count_big(i.event_id) as person_count | ||
from #qualified_events Q | ||
JOIN #inclusion_events i on Q.person_id = I.person_id and Q.event_id = i.event_id | ||
group by i.inclusion_rule_id | ||
) T on ir.rule_sequence = T.inclusion_rule_id | ||
CROSS JOIN (select count(*) as total_rules from #inclusion_rules) RuleTotal | ||
CROSS JOIN (select count_big(event_id) as total from #qualified_events) EventTotal | ||
LEFT JOIN @results_database_schema.cohort_inclusion_result SR on SR.mode_id = 0 AND SR.cohort_definition_id = @target_cohort_id AND (POWER(cast(2 as bigint),RuleTotal.total_rules) - POWER(cast(2 as bigint),ir.rule_sequence) - 1) = SR.inclusion_rule_mask -- POWER(2,rule count) - POWER(2,rule sequence) - 1 is the mask for 'all except this rule' | ||
; | ||
|
||
-- calculate totals | ||
delete from @results_database_schema.cohort_summary_stats where cohort_definition_id = @target_cohort_id and mode_id = 0; | ||
insert into @results_database_schema.cohort_summary_stats (cohort_definition_id, base_count, final_count, mode_id) | ||
select @target_cohort_id as cohort_definition_id, PC.total as person_count, coalesce(FC.total, 0) as final_count, 0 as mode_id | ||
FROM | ||
(select count_big(event_id) as total from #qualified_events) PC, | ||
(select sum(sr.person_count) as total | ||
from @results_database_schema.cohort_inclusion_result sr | ||
CROSS JOIN (select count(*) as total_rules from #inclusion_rules) RuleTotal | ||
where sr.mode_id = 0 and sr.cohort_definition_id = @target_cohort_id and sr.inclusion_rule_mask = POWER(cast(2 as bigint),RuleTotal.total_rules)-1 | ||
) FC | ||
; | ||
|
||
-- END: Inclusion Impact Analysis - event | ||
|
||
-- BEGIN: Inclusion Impact Analysis - person | ||
-- calculte matching group counts | ||
delete from @results_database_schema.cohort_inclusion_result where cohort_definition_id = @target_cohort_id and mode_id = 1; | ||
insert into @results_database_schema.cohort_inclusion_result (cohort_definition_id, inclusion_rule_mask, person_count, mode_id) | ||
select @target_cohort_id as cohort_definition_id, inclusion_rule_mask, count_big(*) as person_count, 1 as mode_id | ||
from | ||
( | ||
select Q.person_id, Q.event_id, CAST(SUM(coalesce(POWER(cast(2 as bigint), I.inclusion_rule_id), 0)) AS bigint) as inclusion_rule_mask | ||
from #best_events Q | ||
LEFT JOIN #inclusion_events I on q.person_id = i.person_id and q.event_id = i.event_id | ||
GROUP BY Q.person_id, Q.event_id | ||
) MG -- matching groups | ||
group by inclusion_rule_mask | ||
; | ||
|
||
-- calculate gain counts | ||
delete from @results_database_schema.cohort_inclusion_stats where cohort_definition_id = @target_cohort_id and mode_id = 1; | ||
insert into @results_database_schema.cohort_inclusion_stats (cohort_definition_id, rule_sequence, person_count, gain_count, person_total, mode_id) | ||
select @target_cohort_id as cohort_definition_id, ir.rule_sequence, coalesce(T.person_count, 0) as person_count, coalesce(SR.person_count, 0) gain_count, EventTotal.total, 1 as mode_id | ||
from #inclusion_rules ir | ||
left join | ||
( | ||
select i.inclusion_rule_id, count_big(i.event_id) as person_count | ||
from #best_events Q | ||
JOIN #inclusion_events i on Q.person_id = I.person_id and Q.event_id = i.event_id | ||
group by i.inclusion_rule_id | ||
) T on ir.rule_sequence = T.inclusion_rule_id | ||
CROSS JOIN (select count(*) as total_rules from #inclusion_rules) RuleTotal | ||
CROSS JOIN (select count_big(event_id) as total from #best_events) EventTotal | ||
LEFT JOIN @results_database_schema.cohort_inclusion_result SR on SR.mode_id = 1 AND SR.cohort_definition_id = @target_cohort_id AND (POWER(cast(2 as bigint),RuleTotal.total_rules) - POWER(cast(2 as bigint),ir.rule_sequence) - 1) = SR.inclusion_rule_mask -- POWER(2,rule count) - POWER(2,rule sequence) - 1 is the mask for 'all except this rule' | ||
; | ||
|
||
-- calculate totals | ||
delete from @results_database_schema.cohort_summary_stats where cohort_definition_id = @target_cohort_id and mode_id = 1; | ||
insert into @results_database_schema.cohort_summary_stats (cohort_definition_id, base_count, final_count, mode_id) | ||
select @target_cohort_id as cohort_definition_id, PC.total as person_count, coalesce(FC.total, 0) as final_count, 1 as mode_id | ||
FROM | ||
(select count_big(event_id) as total from #best_events) PC, | ||
(select sum(sr.person_count) as total | ||
from @results_database_schema.cohort_inclusion_result sr | ||
CROSS JOIN (select count(*) as total_rules from #inclusion_rules) RuleTotal | ||
where sr.mode_id = 1 and sr.cohort_definition_id = @target_cohort_id and sr.inclusion_rule_mask = POWER(cast(2 as bigint),RuleTotal.total_rules)-1 | ||
) FC | ||
; | ||
|
||
-- END: Inclusion Impact Analysis - person | ||
|
||
TRUNCATE TABLE #best_events; | ||
DROP TABLE #best_events; | ||
|
||
TRUNCATE TABLE #inclusion_rules; | ||
DROP TABLE #inclusion_rules; | ||
} | ||
|
||
TRUNCATE TABLE #strategy_ends; | ||
DROP TABLE #strategy_ends; | ||
|
||
|
||
TRUNCATE TABLE #cohort_rows; | ||
DROP TABLE #cohort_rows; | ||
|
||
TRUNCATE TABLE #final_cohort; | ||
DROP TABLE #final_cohort; | ||
|
||
TRUNCATE TABLE #inclusion_events; | ||
DROP TABLE #inclusion_events; | ||
|
||
TRUNCATE TABLE #qualified_events; | ||
DROP TABLE #qualified_events; | ||
|
||
TRUNCATE TABLE #included_events; | ||
DROP TABLE #included_events; | ||
|
||
TRUNCATE TABLE #Codesets; | ||
DROP TABLE #Codesets; |
Oops, something went wrong.