diff --git a/DESCRIPTION b/DESCRIPTION index 5cb9960..576b156 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: MethodEvaluation Type: Package Title: Package for Evaluation of Estimation Methods -Version: 2.3.0 -Date: 2023-06-30 +Version: 2.3.1 +Date: 2024-12-11 Authors@R: c( person("Martijn", "Schuemie", , "schuemie@ohdsi.org", role = c("aut", "cre")) ) @@ -47,5 +47,5 @@ Suggests: Remotes: ohdsi/FeatureExtraction, ohdsi/Eunomia -RoxygenNote: 7.2.3 +RoxygenNote: 7.3.2 Encoding: UTF-8 diff --git a/NEWS.md b/NEWS.md index 8ddeeab..ac396ff 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,11 @@ +MethodEvaluation 2.3.1 +====================== + +Changes: + +1. Updating Circe-generated SQL (to avoid errors on DataBricks). + + MethodEvaluation 2.3.0 ====================== diff --git a/extras/PackageMaintenance.R b/extras/PackageMaintenance.R index ded6945..53d5b58 100644 --- a/extras/PackageMaintenance.R +++ b/extras/PackageMaintenance.R @@ -97,3 +97,13 @@ OhdsiRTools::insertCohortDefinitionInPackage(1775839, OhdsiRTools::insertCohortDefinitionInPackage(1775840, "thiazides_diuretics", baseUrl = keyring::key_get("ohdsiBaseUrl")) + +# Regenerate SQL for cohort definitions ---------------------------------------- +# Old Circe SQL is outdated? Doesn't run on DataBricks + +cohorts <- list.files("inst/cohorts") +for (cohort in cohorts) { + json <- readLines(file.path("inst/cohorts", cohort)) + sql <- CirceR::buildCohortQuery(json, options = CirceR::createGenerateOptions(generateStats = FALSE)) + SqlRender::writeSql(sql, file.path("inst/sql/sql_server", gsub(".json", ".sql", cohort))) +} diff --git a/inst/sql/sql_server/ace_inhibitors.sql b/inst/sql/sql_server/ace_inhibitors.sql index 2c579c1..fe02a5c 100644 --- a/inst/sql/sql_server/ace_inhibitors.sql +++ b/inst/sql/sql_server/ace_inhibitors.sql @@ -7,48 +7,52 @@ CREATE TABLE #Codesets ( 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 (316866) + select concept_id from @vocabulary_database_schema.CONCEPT where (concept_id in (316866)) UNION select c.concept_id from @vocabulary_database_schema.CONCEPT c join @vocabulary_database_schema.CONCEPT_ANCESTOR ca on c.concept_id = ca.descendant_concept_id - and ca.ancestor_concept_id in (316866) - and c.invalid_reason is null + WHERE c.invalid_reason is null + and (ca.ancestor_concept_id in (316866)) ) I ) C UNION ALL SELECT 3 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 (1335471,1340128,1341927,1363749,1308216,1310756,1373225,1331235,1334456,1342439) + select concept_id from @vocabulary_database_schema.CONCEPT where (concept_id in (1335471,1340128,1341927,1363749,1308216,1310756,1373225,1331235,1334456,1342439)) UNION select c.concept_id from @vocabulary_database_schema.CONCEPT c join @vocabulary_database_schema.CONCEPT_ANCESTOR ca on c.concept_id = ca.descendant_concept_id - and ca.ancestor_concept_id in (1335471,1340128,1341927,1363749,1308216,1310756,1373225,1331235,1334456,1342439) - and c.invalid_reason is null + WHERE c.invalid_reason is null + and (ca.ancestor_concept_id in (1335471,1340128,1341927,1363749,1308216,1310756,1373225,1331235,1334456,1342439)) ) I -) C -; +) C; + +UPDATE STATISTICS #Codesets; -with primary_events (event_id, person_id, start_date, end_date, op_start_date, op_end_date, visit_occurrence_id) as + +SELECT event_id, person_id, start_date, end_date, op_start_date, op_end_date, visit_occurrence_id +INTO #qualified_events +FROM ( --- Begin Primary Events + 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) ordinal, + 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 Exposure Criteria -select C.person_id, C.drug_exposure_id as event_id, C.drug_exposure_start_date as start_date, - COALESCE(C.drug_exposure_end_date, DATEADD(day, 1, C.drug_exposure_start_date)) as end_date, C.drug_concept_id as TARGET_CONCEPT_ID, C.visit_occurrence_id, - C.drug_exposure_start_date as sort_date +select C.person_id, C.drug_exposure_id as event_id, C.start_date, C.end_date, + C.visit_occurrence_id,C.start_date as sort_date from ( - select de.* + select de.person_id,de.drug_exposure_id,de.drug_concept_id,de.visit_occurrence_id,days_supply,quantity,refills,de.drug_exposure_start_date as start_date, COALESCE(de.drug_exposure_end_date, DATEADD(day,de.days_supply,de.drug_exposure_start_date), DATEADD(day,1,de.drug_exposure_start_date)) as end_date FROM @cdm_database_schema.DRUG_EXPOSURE de -JOIN #Codesets codesets on ((de.drug_concept_id = codesets.concept_id and codesets.codeset_id = 3)) +JOIN #Codesets cs on (de.drug_concept_id = cs.concept_id and cs.codeset_id = 3) ) C @@ -60,14 +64,7 @@ JOIN #Codesets codesets on ((de.drug_concept_id = codesets.concept_id and codese ) P -- End Primary Events - -) -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 primary_events pe +) pe ) QE @@ -92,27 +89,26 @@ FROM INNER JOIN ( -- Begin Correlated Criteria -SELECT 0 as index_id, p.person_id, p.event_id +select 0 as index_id, cc.person_id, cc.event_id +from (SELECT p.person_id, p.event_id FROM #qualified_events P -INNER JOIN -( +JOIN ( -- Begin Condition Occurrence Criteria -SELECT C.person_id, C.condition_occurrence_id as event_id, C.condition_start_date as start_date, COALESCE(C.condition_end_date, DATEADD(day,1,C.condition_start_date)) as end_date, - C.CONDITION_CONCEPT_ID as TARGET_CONCEPT_ID, C.visit_occurrence_id, - C.condition_start_date as sort_date +SELECT C.person_id, C.condition_occurrence_id as event_id, C.start_date, C.end_date, + C.visit_occurrence_id, C.start_date as sort_date FROM ( - SELECT co.* + SELECT co.person_id,co.condition_occurrence_id,co.condition_concept_id,co.visit_occurrence_id,co.condition_start_date as start_date, COALESCE(co.condition_end_date, DATEADD(day,1,co.condition_start_date)) as end_date FROM @cdm_database_schema.CONDITION_OCCURRENCE co - JOIN #Codesets codesets on ((co.condition_concept_id = codesets.concept_id and codesets.codeset_id = 0)) + JOIN #Codesets cs on (co.condition_concept_id = cs.concept_id and cs.codeset_id = 0) ) C -- End Condition Occurrence Criteria -) A on A.person_id = P.person_id AND A.START_DATE >= P.OP_START_DATE AND A.START_DATE <= P.OP_END_DATE AND A.START_DATE >= P.OP_START_DATE AND A.START_DATE <= P.OP_END_DATE -GROUP BY p.person_id, p.event_id -HAVING COUNT(A.TARGET_CONCEPT_ID) >= 1 +) A on A.person_id = P.person_id AND A.START_DATE >= P.OP_START_DATE AND A.START_DATE <= P.OP_END_DATE AND A.START_DATE >= P.OP_START_DATE AND A.START_DATE <= P.OP_END_DATE ) cc +GROUP BY cc.person_id, cc.event_id +HAVING COUNT(cc.event_id) >= 1 -- End Correlated Criteria ) CQ on E.person_id = CQ.person_id and E.event_id = CQ.event_id @@ -131,8 +127,9 @@ TRUNCATE TABLE #Inclusion_0; DROP TABLE #Inclusion_0; -with cteIncludedEvents(event_id, person_id, start_date, end_date, op_start_date, op_end_date, ordinal) as -( +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 ( @@ -141,14 +138,11 @@ with cteIncludedEvents(event_id, person_id, start_date, end_date, op_start_date, 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 - +{1 != 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),1)-1) - -) -select event_id, person_id, start_date, end_date, op_start_date, op_end_date -into #included_events -FROM cteIncludedEvents Results +} +) Results ; @@ -161,14 +155,14 @@ with ctePersons(person_id) as ( 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 + 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 = 3 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 + 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 = 3 AND de.drug_source_concept_id = cs.concept_id @@ -180,38 +174,20 @@ 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 ROWS UNBOUNDED PRECEDING) AS start_ordinal, - ROW_NUMBER() OVER (PARTITION BY PERSON_ID ORDER BY EVENT_DATE, EVENT_TYPE) 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 + + select person_id, min(start_date) as era_start_date, DATEADD(day,-1 * 30, max(end_date)) as era_end_date + from ( + select person_id, start_date, end_date, sum(is_start) over (partition by person_id order by start_date, is_start desc rows unbounded preceding) group_idx + from ( + select person_id, start_date, end_date, + case when max(end_date) over (partition by person_id order by start_date rows between unbounded preceding and 1 preceding) >= start_date then 0 else 1 end is_start + from ( + select person_id, drug_exposure_start_date as start_date, DATEADD(day,(30 + 0),DRUG_EXPOSURE_END_DATE) as end_date + FROM #drugTarget + ) DT + ) ST + ) GR + group by person_id, group_idx ) ERAS on ERAS.person_id = et.person_id WHERE et.start_date between ERAS.era_start_date and ERAS.era_end_date; @@ -220,80 +196,41 @@ DROP TABLE #drugTarget; -- generate cohort periods into #final_cohort -with cohort_ends (event_id, person_id, end_date) as -( - -- cohort exit dates - -- By default, cohort exit at the event's op end date +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 -), -first_ends (person_id, start_date, end_date) as -( - select F.person_id, F.start_date, F.end_date - FROM ( - select I.event_id, I.person_id, I.start_date, E.end_date, row_number() over (partition by I.person_id, I.event_id order by E.end_date) as ordinal - from #included_events I - join cohort_ends E on I.event_id = E.event_id and I.person_id = E.person_id and E.end_date >= I.start_date + ) 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 -) -select person_id, start_date, end_date -INTO #cohort_rows -from first_ends; - -with cteEndDates (person_id, end_date) AS -- the magic -( - SELECT - person_id - , DATEADD(day,-1 * 0, event_date) as end_date - FROM - ( - SELECT - person_id - , event_date - , event_type - , MAX(start_ordinal) OVER (PARTITION BY person_id ORDER BY event_date, event_type ROWS UNBOUNDED PRECEDING) AS start_ordinal - , ROW_NUMBER() OVER (PARTITION BY person_id ORDER BY event_date, event_type) AS overall_ord - FROM - ( - SELECT - person_id - , start_date AS event_date - , -1 AS event_type - , ROW_NUMBER() OVER (PARTITION BY person_id ORDER BY start_date) AS start_ordinal - FROM #cohort_rows - - UNION ALL - - - SELECT - person_id - , DATEADD(day,0,end_date) as end_date - , 1 AS event_type - , NULL - FROM #cohort_rows - ) RAWDATA - ) e - WHERE (2 * e.start_ordinal) - e.overall_ord = 0 -), -cteEnds (person_id, start_date, end_date) AS -( - SELECT - c.person_id - , c.start_date - , MIN(e.end_date) AS end_date - FROM #cohort_rows c - JOIN cteEndDates e ON c.person_id = e.person_id AND e.end_date >= c.start_date - GROUP BY c.person_id, c.start_date -) -select person_id, min(start_date) as start_date, end_date +) FE; + + +select person_id, min(start_date) as start_date, DATEADD(day,-1 * 0, max(end_date)) as end_date into #final_cohort -from cteEnds -group by person_id, end_date -; +from ( + select person_id, start_date, end_date, sum(is_start) over (partition by person_id order by start_date, is_start desc rows unbounded preceding) group_idx + from ( + select person_id, start_date, end_date, + case when max(end_date) over (partition by person_id order by start_date rows between unbounded preceding and 1 preceding) >= start_date then 0 else 1 end is_start + from ( + select person_id, start_date, DATEADD(day,0,end_date) as end_date + from #cohort_rows + ) CR + ) ST +) GR +group by person_id, group_idx; 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) @@ -301,7 +238,148 @@ select @target_cohort_id as cohort_definition_id, person_id, start_date, end_dat 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 & 1 != 0}?{ + +-- Create a temp table of inclusion rule rows for joining in the inclusion rule impact analysis + +select cast(rule_sequence as int) as rule_sequence +into #inclusion_rules +from ( + SELECT CAST(0 as int) as rule_sequence +) IR; + + +-- 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; @@ -324,4 +402,3 @@ DROP TABLE #included_events; TRUNCATE TABLE #Codesets; DROP TABLE #Codesets; - diff --git a/inst/sql/sql_server/acute_pancreatitis.sql b/inst/sql/sql_server/acute_pancreatitis.sql index 939c03e..222ad51 100644 --- a/inst/sql/sql_server/acute_pancreatitis.sql +++ b/inst/sql/sql_server/acute_pancreatitis.sql @@ -7,33 +7,41 @@ CREATE TABLE #Codesets ( 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 (199074)and invalid_reason is null + select concept_id from @vocabulary_database_schema.CONCEPT where (concept_id in (199074)) UNION select c.concept_id from @vocabulary_database_schema.CONCEPT c join @vocabulary_database_schema.CONCEPT_ANCESTOR ca on c.concept_id = ca.descendant_concept_id - and ca.ancestor_concept_id in (199074) - and c.invalid_reason is null + WHERE c.invalid_reason is null + and (ca.ancestor_concept_id in (199074)) ) I ) C; +UPDATE STATISTICS #Codesets; -with primary_events (event_id, person_id, start_date, end_date, op_start_date, op_end_date, visit_occurrence_id) as + +SELECT event_id, person_id, start_date, end_date, op_start_date, op_end_date, visit_occurrence_id +INTO #qualified_events +FROM ( --- Begin Primary Events + 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.start_date ASC) 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 + 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 Condition Occurrence Criteria -SELECT C.person_id, C.condition_occurrence_id as event_id, C.condition_start_date as start_date, COALESCE(C.condition_end_date, DATEADD(day,1,C.condition_start_date)) as end_date, C.CONDITION_CONCEPT_ID as TARGET_CONCEPT_ID, C.visit_occurrence_id +SELECT C.person_id, C.condition_occurrence_id as event_id, C.start_date, C.end_date, + C.visit_occurrence_id, C.start_date as sort_date FROM ( - SELECT co.* + SELECT co.person_id,co.condition_occurrence_id,co.condition_concept_id,co.visit_occurrence_id,co.condition_type_concept_id,co.condition_start_date as start_date, COALESCE(co.condition_end_date, DATEADD(day,1,co.condition_start_date)) as end_date FROM @cdm_database_schema.CONDITION_OCCURRENCE co - JOIN #Codesets codesets on ((co.condition_concept_id = codesets.concept_id and codesets.codeset_id = 0)) + JOIN #Codesets cs on (co.condition_concept_id = cs.concept_id and cs.codeset_id = 0) ) C JOIN @cdm_database_schema.VISIT_OCCURRENCE V on C.visit_occurrence_id = V.visit_occurrence_id and C.person_id = V.person_id WHERE C.condition_type_concept_id in (38000183,38000248,38000199,38000250,44786627,38000184) @@ -46,14 +54,7 @@ AND V.visit_concept_id in (9203,9201) ) P WHERE P.ordinal = 1 -- End Primary Events - -) -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 primary_events pe +) pe ) QE @@ -66,8 +67,9 @@ create table #inclusion_events (inclusion_rule_id bigint, event_id bigint ); -with cteIncludedEvents(event_id, person_id, start_date, end_date, op_start_date, op_end_date, ordinal) as -( +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 ( @@ -76,87 +78,48 @@ with cteIncludedEvents(event_id, person_id, start_date, end_date, op_start_date, 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 - -) -select event_id, person_id, start_date, end_date, op_start_date, op_end_date -into #included_events -FROM cteIncludedEvents Results +{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 ; -- generate cohort periods into #final_cohort -with cohort_ends (event_id, person_id, end_date) as -( - -- 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 -), -first_ends (person_id, start_date, end_date) as -( +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, E.end_date, row_number() over (partition by I.person_id, I.event_id order by E.end_date) as ordinal + 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 E on I.event_id = E.event_id and I.person_id = E.person_id and E.end_date >= I.start_date + 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 + ) 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 -) -select person_id, start_date, end_date -INTO #cohort_rows -from first_ends; - -with cteEndDates (person_id, end_date) AS -- the magic -( - SELECT - person_id - , DATEADD(day,-1 * 0, event_date) as end_date - FROM - ( - SELECT - person_id - , event_date - , event_type - , MAX(start_ordinal) OVER (PARTITION BY person_id ORDER BY event_date, event_type ROWS UNBOUNDED PRECEDING) AS start_ordinal - , ROW_NUMBER() OVER (PARTITION BY person_id ORDER BY event_date, event_type) AS overall_ord - FROM - ( - SELECT - person_id - , start_date AS event_date - , -1 AS event_type - , ROW_NUMBER() OVER (PARTITION BY person_id ORDER BY start_date) AS start_ordinal - FROM #cohort_rows - - UNION ALL - - - SELECT - person_id - , DATEADD(day,0,end_date) as end_date - , 1 AS event_type - , NULL - FROM #cohort_rows - ) RAWDATA - ) e - WHERE (2 * e.start_ordinal) - e.overall_ord = 0 -), -cteEnds (person_id, start_date, end_date) AS -( - SELECT - c.person_id - , c.start_date - , MIN(e.end_date) AS era_end_date - FROM #cohort_rows c - JOIN cteEndDates e ON c.person_id = e.person_id AND e.end_date >= c.start_date - GROUP BY c.person_id, c.start_date -) -select person_id, min(start_date) as start_date, end_date +) FE; + + +select person_id, min(start_date) as start_date, DATEADD(day,-1 * 0, max(end_date)) as end_date into #final_cohort -from cteEnds -group by person_id, end_date -; +from ( + select person_id, start_date, end_date, sum(is_start) over (partition by person_id order by start_date, is_start desc rows unbounded preceding) group_idx + from ( + select person_id, start_date, end_date, + case when max(end_date) over (partition by person_id order by start_date rows between unbounded preceding and 1 preceding) >= start_date then 0 else 1 end is_start + from ( + select person_id, start_date, DATEADD(day,0,end_date) as end_date + from #cohort_rows + ) CR + ) ST +) GR +group by person_id, group_idx; 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) @@ -164,7 +127,141 @@ select @target_cohort_id as cohort_definition_id, person_id, start_date, end_dat 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; +} @@ -185,4 +282,3 @@ DROP TABLE #included_events; TRUNCATE TABLE #Codesets; DROP TABLE #Codesets; - diff --git a/inst/sql/sql_server/gi_bleed.sql b/inst/sql/sql_server/gi_bleed.sql index 6ba1398..6f48465 100644 --- a/inst/sql/sql_server/gi_bleed.sql +++ b/inst/sql/sql_server/gi_bleed.sql @@ -7,44 +7,52 @@ CREATE TABLE #Codesets ( INSERT INTO #Codesets (codeset_id, concept_id) SELECT 2 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 (4280942,28779,198798,4112183,194382,192671,196436,4338225,194690,443530,194395,4048064)and invalid_reason is null + select concept_id from @vocabulary_database_schema.CONCEPT where (concept_id in (4280942,28779,198798,4112183,194382,192671,196436,4338225,194690,443530,194395,4048064)) UNION select c.concept_id from @vocabulary_database_schema.CONCEPT c join @vocabulary_database_schema.CONCEPT_ANCESTOR ca on c.concept_id = ca.descendant_concept_id - and ca.ancestor_concept_id in (4280942,28779,198798,4112183,192671,4338225,194395,4048064) - and c.invalid_reason is null + WHERE c.invalid_reason is null + and (ca.ancestor_concept_id in (4280942,28779,198798,4112183,192671,4338225,194395,4048064)) ) I LEFT JOIN ( - select concept_id from @vocabulary_database_schema.CONCEPT where concept_id in (194158)and invalid_reason is null + select concept_id from @vocabulary_database_schema.CONCEPT where (concept_id in (194158)) UNION select c.concept_id from @vocabulary_database_schema.CONCEPT c join @vocabulary_database_schema.CONCEPT_ANCESTOR ca on c.concept_id = ca.descendant_concept_id - and ca.ancestor_concept_id in (194158) - and c.invalid_reason is null + WHERE c.invalid_reason is null + and (ca.ancestor_concept_id in (194158)) ) E ON I.concept_id = E.concept_id WHERE E.concept_id is null ) C; +UPDATE STATISTICS #Codesets; -with primary_events (event_id, person_id, start_date, end_date, op_start_date, op_end_date, visit_occurrence_id) as + +SELECT event_id, person_id, start_date, end_date, op_start_date, op_end_date, visit_occurrence_id +INTO #qualified_events +FROM ( --- Begin Primary Events + 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.start_date ASC) 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 + 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 Condition Occurrence Criteria -SELECT C.person_id, C.condition_occurrence_id as event_id, C.condition_start_date as start_date, COALESCE(C.condition_end_date, DATEADD(day,1,C.condition_start_date)) as end_date, C.CONDITION_CONCEPT_ID as TARGET_CONCEPT_ID, C.visit_occurrence_id +SELECT C.person_id, C.condition_occurrence_id as event_id, C.start_date, C.end_date, + C.visit_occurrence_id, C.start_date as sort_date FROM ( - SELECT co.* + SELECT co.person_id,co.condition_occurrence_id,co.condition_concept_id,co.visit_occurrence_id,co.condition_type_concept_id,co.condition_start_date as start_date, COALESCE(co.condition_end_date, DATEADD(day,1,co.condition_start_date)) as end_date FROM @cdm_database_schema.CONDITION_OCCURRENCE co - JOIN #Codesets codesets on ((co.condition_concept_id = codesets.concept_id and codesets.codeset_id = 2)) + JOIN #Codesets cs on (co.condition_concept_id = cs.concept_id and cs.codeset_id = 2) ) C JOIN @cdm_database_schema.VISIT_OCCURRENCE V on C.visit_occurrence_id = V.visit_occurrence_id and C.person_id = V.person_id WHERE C.condition_type_concept_id in (38000183,38000199,44786627,38000184,38000200) @@ -57,14 +65,7 @@ AND V.visit_concept_id in (9203,9201) ) P WHERE P.ordinal = 1 -- End Primary Events - -) -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 primary_events pe +) pe ) QE @@ -77,8 +78,9 @@ create table #inclusion_events (inclusion_rule_id bigint, event_id bigint ); -with cteIncludedEvents(event_id, person_id, start_date, end_date, op_start_date, op_end_date, ordinal) as -( +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 ( @@ -87,87 +89,48 @@ with cteIncludedEvents(event_id, person_id, start_date, end_date, op_start_date, 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 - -) -select event_id, person_id, start_date, end_date, op_start_date, op_end_date -into #included_events -FROM cteIncludedEvents Results +{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 ; -- generate cohort periods into #final_cohort -with cohort_ends (event_id, person_id, end_date) as -( - -- 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 -), -first_ends (person_id, start_date, end_date) as -( +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, E.end_date, row_number() over (partition by I.person_id, I.event_id order by E.end_date) as ordinal + 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 E on I.event_id = E.event_id and I.person_id = E.person_id and E.end_date >= I.start_date + 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 + ) 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 -) -select person_id, start_date, end_date -INTO #cohort_rows -from first_ends; - -with cteEndDates (person_id, end_date) AS -- the magic -( - SELECT - person_id - , DATEADD(day,-1 * 0, event_date) as end_date - FROM - ( - SELECT - person_id - , event_date - , event_type - , MAX(start_ordinal) OVER (PARTITION BY person_id ORDER BY event_date, event_type ROWS UNBOUNDED PRECEDING) AS start_ordinal - , ROW_NUMBER() OVER (PARTITION BY person_id ORDER BY event_date, event_type) AS overall_ord - FROM - ( - SELECT - person_id - , start_date AS event_date - , -1 AS event_type - , ROW_NUMBER() OVER (PARTITION BY person_id ORDER BY start_date) AS start_ordinal - FROM #cohort_rows - - UNION ALL - - - SELECT - person_id - , DATEADD(day,0,end_date) as end_date - , 1 AS event_type - , NULL - FROM #cohort_rows - ) RAWDATA - ) e - WHERE (2 * e.start_ordinal) - e.overall_ord = 0 -), -cteEnds (person_id, start_date, end_date) AS -( - SELECT - c.person_id - , c.start_date - , MIN(e.end_date) AS era_end_date - FROM #cohort_rows c - JOIN cteEndDates e ON c.person_id = e.person_id AND e.end_date >= c.start_date - GROUP BY c.person_id, c.start_date -) -select person_id, min(start_date) as start_date, end_date +) FE; + + +select person_id, min(start_date) as start_date, DATEADD(day,-1 * 0, max(end_date)) as end_date into #final_cohort -from cteEnds -group by person_id, end_date -; +from ( + select person_id, start_date, end_date, sum(is_start) over (partition by person_id order by start_date, is_start desc rows unbounded preceding) group_idx + from ( + select person_id, start_date, end_date, + case when max(end_date) over (partition by person_id order by start_date rows between unbounded preceding and 1 preceding) >= start_date then 0 else 1 end is_start + from ( + select person_id, start_date, DATEADD(day,0,end_date) as end_date + from #cohort_rows + ) CR + ) ST +) GR +group by person_id, group_idx; 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) @@ -175,7 +138,141 @@ select @target_cohort_id as cohort_definition_id, person_id, start_date, end_dat 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; +} @@ -196,4 +293,3 @@ DROP TABLE #included_events; TRUNCATE TABLE #Codesets; DROP TABLE #Codesets; - diff --git a/inst/sql/sql_server/ibd.sql b/inst/sql/sql_server/ibd.sql index bf9d44a..d0a5f6c 100644 --- a/inst/sql/sql_server/ibd.sql +++ b/inst/sql/sql_server/ibd.sql @@ -7,33 +7,41 @@ CREATE TABLE #Codesets ( 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 (4074815)and invalid_reason is null + select concept_id from @vocabulary_database_schema.CONCEPT where (concept_id in (4074815)) UNION select c.concept_id from @vocabulary_database_schema.CONCEPT c join @vocabulary_database_schema.CONCEPT_ANCESTOR ca on c.concept_id = ca.descendant_concept_id - and ca.ancestor_concept_id in (4074815) - and c.invalid_reason is null + WHERE c.invalid_reason is null + and (ca.ancestor_concept_id in (4074815)) ) I ) C; +UPDATE STATISTICS #Codesets; -with primary_events (event_id, person_id, start_date, end_date, op_start_date, op_end_date, visit_occurrence_id) as + +SELECT event_id, person_id, start_date, end_date, op_start_date, op_end_date, visit_occurrence_id +INTO #qualified_events +FROM ( --- Begin Primary Events + 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.start_date ASC) 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 + 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 Condition Occurrence Criteria -SELECT C.person_id, C.condition_occurrence_id as event_id, C.condition_start_date as start_date, COALESCE(C.condition_end_date, DATEADD(day,1,C.condition_start_date)) as end_date, C.CONDITION_CONCEPT_ID as TARGET_CONCEPT_ID, C.visit_occurrence_id +SELECT C.person_id, C.condition_occurrence_id as event_id, C.start_date, C.end_date, + C.visit_occurrence_id, C.start_date as sort_date FROM ( - SELECT co.* + SELECT co.person_id,co.condition_occurrence_id,co.condition_concept_id,co.visit_occurrence_id,co.condition_start_date as start_date, COALESCE(co.condition_end_date, DATEADD(day,1,co.condition_start_date)) as end_date FROM @cdm_database_schema.CONDITION_OCCURRENCE co - JOIN #Codesets codesets on ((co.condition_concept_id = codesets.concept_id and codesets.codeset_id = 0)) + JOIN #Codesets cs on (co.condition_concept_id = cs.concept_id and cs.codeset_id = 0) ) C @@ -45,14 +53,7 @@ FROM ) P WHERE P.ordinal = 1 -- End Primary Events - -) -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 primary_events pe +) pe ) QE @@ -65,8 +66,9 @@ create table #inclusion_events (inclusion_rule_id bigint, event_id bigint ); -with cteIncludedEvents(event_id, person_id, start_date, end_date, op_start_date, op_end_date, ordinal) as -( +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 ( @@ -75,87 +77,48 @@ with cteIncludedEvents(event_id, person_id, start_date, end_date, op_start_date, 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 - -) -select event_id, person_id, start_date, end_date, op_start_date, op_end_date -into #included_events -FROM cteIncludedEvents Results +{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 ; -- generate cohort periods into #final_cohort -with cohort_ends (event_id, person_id, end_date) as -( - -- 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 -), -first_ends (person_id, start_date, end_date) as -( +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, E.end_date, row_number() over (partition by I.person_id, I.event_id order by E.end_date) as ordinal + 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 E on I.event_id = E.event_id and I.person_id = E.person_id and E.end_date >= I.start_date + 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 + ) 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 -) -select person_id, start_date, end_date -INTO #cohort_rows -from first_ends; - -with cteEndDates (person_id, end_date) AS -- the magic -( - SELECT - person_id - , DATEADD(day,-1 * 0, event_date) as end_date - FROM - ( - SELECT - person_id - , event_date - , event_type - , MAX(start_ordinal) OVER (PARTITION BY person_id ORDER BY event_date, event_type ROWS UNBOUNDED PRECEDING) AS start_ordinal - , ROW_NUMBER() OVER (PARTITION BY person_id ORDER BY event_date, event_type) AS overall_ord - FROM - ( - SELECT - person_id - , start_date AS event_date - , -1 AS event_type - , ROW_NUMBER() OVER (PARTITION BY person_id ORDER BY start_date) AS start_ordinal - FROM #cohort_rows - - UNION ALL - - - SELECT - person_id - , DATEADD(day,0,end_date) as end_date - , 1 AS event_type - , NULL - FROM #cohort_rows - ) RAWDATA - ) e - WHERE (2 * e.start_ordinal) - e.overall_ord = 0 -), -cteEnds (person_id, start_date, end_date) AS -( - SELECT - c.person_id - , c.start_date - , MIN(e.end_date) AS era_end_date - FROM #cohort_rows c - JOIN cteEndDates e ON c.person_id = e.person_id AND e.end_date >= c.start_date - GROUP BY c.person_id, c.start_date -) -select person_id, min(start_date) as start_date, end_date +) FE; + + +select person_id, min(start_date) as start_date, DATEADD(day,-1 * 0, max(end_date)) as end_date into #final_cohort -from cteEnds -group by person_id, end_date -; +from ( + select person_id, start_date, end_date, sum(is_start) over (partition by person_id order by start_date, is_start desc rows unbounded preceding) group_idx + from ( + select person_id, start_date, end_date, + case when max(end_date) over (partition by person_id order by start_date rows between unbounded preceding and 1 preceding) >= start_date then 0 else 1 end is_start + from ( + select person_id, start_date, DATEADD(day,0,end_date) as end_date + from #cohort_rows + ) CR + ) ST +) GR +group by person_id, group_idx; 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) @@ -163,7 +126,141 @@ select @target_cohort_id as cohort_definition_id, person_id, start_date, end_dat 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; +} @@ -184,4 +281,3 @@ DROP TABLE #included_events; TRUNCATE TABLE #Codesets; DROP TABLE #Codesets; - diff --git a/inst/sql/sql_server/stroke.sql b/inst/sql/sql_server/stroke.sql index 9710ea1..46cbc96 100644 --- a/inst/sql/sql_server/stroke.sql +++ b/inst/sql/sql_server/stroke.sql @@ -7,44 +7,52 @@ CREATE TABLE #Codesets ( 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 (374060,376713,4108356,4110192,4043731,432923)and invalid_reason is null + select concept_id from @vocabulary_database_schema.CONCEPT where (concept_id in (374060,376713,4108356,4110192,4043731,432923)) UNION select c.concept_id from @vocabulary_database_schema.CONCEPT c join @vocabulary_database_schema.CONCEPT_ANCESTOR ca on c.concept_id = ca.descendant_concept_id - and ca.ancestor_concept_id in (374060,376713,4108356,4110192,4043731,432923) - and c.invalid_reason is null + WHERE c.invalid_reason is null + and (ca.ancestor_concept_id in (374060,376713,4108356,4110192,4043731,432923)) ) I LEFT JOIN ( - select concept_id from @vocabulary_database_schema.CONCEPT where concept_id in (4345688,42873157,260841,441709,443752)and invalid_reason is null + select concept_id from @vocabulary_database_schema.CONCEPT where (concept_id in (4345688,42873157,260841,441709,443752)) UNION select c.concept_id from @vocabulary_database_schema.CONCEPT c join @vocabulary_database_schema.CONCEPT_ANCESTOR ca on c.concept_id = ca.descendant_concept_id - and ca.ancestor_concept_id in (4345688,42873157,260841,441709,443752) - and c.invalid_reason is null + WHERE c.invalid_reason is null + and (ca.ancestor_concept_id in (4345688,42873157,260841,441709,443752)) ) E ON I.concept_id = E.concept_id WHERE E.concept_id is null ) C; +UPDATE STATISTICS #Codesets; -with primary_events (event_id, person_id, start_date, end_date, op_start_date, op_end_date, visit_occurrence_id) as + +SELECT event_id, person_id, start_date, end_date, op_start_date, op_end_date, visit_occurrence_id +INTO #qualified_events +FROM ( --- Begin Primary Events + 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.start_date ASC) 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 + 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 Condition Occurrence Criteria -SELECT C.person_id, C.condition_occurrence_id as event_id, C.condition_start_date as start_date, COALESCE(C.condition_end_date, DATEADD(day,1,C.condition_start_date)) as end_date, C.CONDITION_CONCEPT_ID as TARGET_CONCEPT_ID, C.visit_occurrence_id +SELECT C.person_id, C.condition_occurrence_id as event_id, C.start_date, C.end_date, + C.visit_occurrence_id, C.start_date as sort_date FROM ( - SELECT co.* + SELECT co.person_id,co.condition_occurrence_id,co.condition_concept_id,co.visit_occurrence_id,co.condition_type_concept_id,co.condition_start_date as start_date, COALESCE(co.condition_end_date, DATEADD(day,1,co.condition_start_date)) as end_date FROM @cdm_database_schema.CONDITION_OCCURRENCE co - JOIN #Codesets codesets on ((co.condition_concept_id = codesets.concept_id and codesets.codeset_id = 0)) + JOIN #Codesets cs on (co.condition_concept_id = cs.concept_id and cs.codeset_id = 0) ) C JOIN @cdm_database_schema.VISIT_OCCURRENCE V on C.visit_occurrence_id = V.visit_occurrence_id and C.person_id = V.person_id WHERE C.condition_type_concept_id in (38000183,38000248,38000199,38000250,44786627,38000184) @@ -57,14 +65,7 @@ AND V.visit_concept_id in (9203,9201) ) P WHERE P.ordinal = 1 -- End Primary Events - -) -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 primary_events pe +) pe ) QE @@ -77,8 +78,9 @@ create table #inclusion_events (inclusion_rule_id bigint, event_id bigint ); -with cteIncludedEvents(event_id, person_id, start_date, end_date, op_start_date, op_end_date, ordinal) as -( +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 ( @@ -87,87 +89,48 @@ with cteIncludedEvents(event_id, person_id, start_date, end_date, op_start_date, 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 - -) -select event_id, person_id, start_date, end_date, op_start_date, op_end_date -into #included_events -FROM cteIncludedEvents Results +{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 ; -- generate cohort periods into #final_cohort -with cohort_ends (event_id, person_id, end_date) as -( - -- 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 -), -first_ends (person_id, start_date, end_date) as -( +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, E.end_date, row_number() over (partition by I.person_id, I.event_id order by E.end_date) as ordinal + 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 E on I.event_id = E.event_id and I.person_id = E.person_id and E.end_date >= I.start_date + 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 + ) 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 -) -select person_id, start_date, end_date -INTO #cohort_rows -from first_ends; - -with cteEndDates (person_id, end_date) AS -- the magic -( - SELECT - person_id - , DATEADD(day,-1 * 0, event_date) as end_date - FROM - ( - SELECT - person_id - , event_date - , event_type - , MAX(start_ordinal) OVER (PARTITION BY person_id ORDER BY event_date, event_type ROWS UNBOUNDED PRECEDING) AS start_ordinal - , ROW_NUMBER() OVER (PARTITION BY person_id ORDER BY event_date, event_type) AS overall_ord - FROM - ( - SELECT - person_id - , start_date AS event_date - , -1 AS event_type - , ROW_NUMBER() OVER (PARTITION BY person_id ORDER BY start_date) AS start_ordinal - FROM #cohort_rows - - UNION ALL - - - SELECT - person_id - , DATEADD(day,0,end_date) as end_date - , 1 AS event_type - , NULL - FROM #cohort_rows - ) RAWDATA - ) e - WHERE (2 * e.start_ordinal) - e.overall_ord = 0 -), -cteEnds (person_id, start_date, end_date) AS -( - SELECT - c.person_id - , c.start_date - , MIN(e.end_date) AS era_end_date - FROM #cohort_rows c - JOIN cteEndDates e ON c.person_id = e.person_id AND e.end_date >= c.start_date - GROUP BY c.person_id, c.start_date -) -select person_id, min(start_date) as start_date, end_date +) FE; + + +select person_id, min(start_date) as start_date, DATEADD(day,-1 * 0, max(end_date)) as end_date into #final_cohort -from cteEnds -group by person_id, end_date -; +from ( + select person_id, start_date, end_date, sum(is_start) over (partition by person_id order by start_date, is_start desc rows unbounded preceding) group_idx + from ( + select person_id, start_date, end_date, + case when max(end_date) over (partition by person_id order by start_date rows between unbounded preceding and 1 preceding) >= start_date then 0 else 1 end is_start + from ( + select person_id, start_date, DATEADD(day,0,end_date) as end_date + from #cohort_rows + ) CR + ) ST +) GR +group by person_id, group_idx; 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) @@ -175,7 +138,141 @@ select @target_cohort_id as cohort_definition_id, person_id, start_date, end_dat 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; +} @@ -196,4 +293,3 @@ DROP TABLE #included_events; TRUNCATE TABLE #Codesets; DROP TABLE #Codesets; - diff --git a/inst/sql/sql_server/thiazides_diuretics.sql b/inst/sql/sql_server/thiazides_diuretics.sql index c80f5d5..cfc6d2e 100644 --- a/inst/sql/sql_server/thiazides_diuretics.sql +++ b/inst/sql/sql_server/thiazides_diuretics.sql @@ -7,48 +7,52 @@ CREATE TABLE #Codesets ( 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 (316866) + select concept_id from @vocabulary_database_schema.CONCEPT where (concept_id in (316866)) UNION select c.concept_id from @vocabulary_database_schema.CONCEPT c join @vocabulary_database_schema.CONCEPT_ANCESTOR ca on c.concept_id = ca.descendant_concept_id - and ca.ancestor_concept_id in (316866) - and c.invalid_reason is null + WHERE c.invalid_reason is null + and (ca.ancestor_concept_id in (316866)) ) I ) C UNION ALL SELECT 4 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 (1395058,974166,978555,907013) + select concept_id from @vocabulary_database_schema.CONCEPT where (concept_id in (1395058,974166,978555,907013)) UNION select c.concept_id from @vocabulary_database_schema.CONCEPT c join @vocabulary_database_schema.CONCEPT_ANCESTOR ca on c.concept_id = ca.descendant_concept_id - and ca.ancestor_concept_id in (1395058,974166,978555,907013) - and c.invalid_reason is null + WHERE c.invalid_reason is null + and (ca.ancestor_concept_id in (1395058,974166,978555,907013)) ) I -) C -; +) C; + +UPDATE STATISTICS #Codesets; -with primary_events (event_id, person_id, start_date, end_date, op_start_date, op_end_date, visit_occurrence_id) as + +SELECT event_id, person_id, start_date, end_date, op_start_date, op_end_date, visit_occurrence_id +INTO #qualified_events +FROM ( --- Begin Primary Events + 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) ordinal, + 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 Exposure Criteria -select C.person_id, C.drug_exposure_id as event_id, C.drug_exposure_start_date as start_date, - COALESCE(C.drug_exposure_end_date, DATEADD(day, 1, C.drug_exposure_start_date)) as end_date, C.drug_concept_id as TARGET_CONCEPT_ID, C.visit_occurrence_id, - C.drug_exposure_start_date as sort_date +select C.person_id, C.drug_exposure_id as event_id, C.start_date, C.end_date, + C.visit_occurrence_id,C.start_date as sort_date from ( - select de.* + select de.person_id,de.drug_exposure_id,de.drug_concept_id,de.visit_occurrence_id,days_supply,quantity,refills,de.drug_exposure_start_date as start_date, COALESCE(de.drug_exposure_end_date, DATEADD(day,de.days_supply,de.drug_exposure_start_date), DATEADD(day,1,de.drug_exposure_start_date)) as end_date FROM @cdm_database_schema.DRUG_EXPOSURE de -JOIN #Codesets codesets on ((de.drug_concept_id = codesets.concept_id and codesets.codeset_id = 4)) +JOIN #Codesets cs on (de.drug_concept_id = cs.concept_id and cs.codeset_id = 4) ) C @@ -60,14 +64,7 @@ JOIN #Codesets codesets on ((de.drug_concept_id = codesets.concept_id and codese ) P -- End Primary Events - -) -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 primary_events pe +) pe ) QE @@ -92,27 +89,26 @@ FROM INNER JOIN ( -- Begin Correlated Criteria -SELECT 0 as index_id, p.person_id, p.event_id +select 0 as index_id, cc.person_id, cc.event_id +from (SELECT p.person_id, p.event_id FROM #qualified_events P -INNER JOIN -( +JOIN ( -- Begin Condition Occurrence Criteria -SELECT C.person_id, C.condition_occurrence_id as event_id, C.condition_start_date as start_date, COALESCE(C.condition_end_date, DATEADD(day,1,C.condition_start_date)) as end_date, - C.CONDITION_CONCEPT_ID as TARGET_CONCEPT_ID, C.visit_occurrence_id, - C.condition_start_date as sort_date +SELECT C.person_id, C.condition_occurrence_id as event_id, C.start_date, C.end_date, + C.visit_occurrence_id, C.start_date as sort_date FROM ( - SELECT co.* + SELECT co.person_id,co.condition_occurrence_id,co.condition_concept_id,co.visit_occurrence_id,co.condition_start_date as start_date, COALESCE(co.condition_end_date, DATEADD(day,1,co.condition_start_date)) as end_date FROM @cdm_database_schema.CONDITION_OCCURRENCE co - JOIN #Codesets codesets on ((co.condition_concept_id = codesets.concept_id and codesets.codeset_id = 0)) + JOIN #Codesets cs on (co.condition_concept_id = cs.concept_id and cs.codeset_id = 0) ) C -- End Condition Occurrence Criteria -) A on A.person_id = P.person_id AND A.START_DATE >= P.OP_START_DATE AND A.START_DATE <= P.OP_END_DATE AND A.START_DATE >= P.OP_START_DATE AND A.START_DATE <= P.OP_END_DATE -GROUP BY p.person_id, p.event_id -HAVING COUNT(A.TARGET_CONCEPT_ID) >= 1 +) A on A.person_id = P.person_id AND A.START_DATE >= P.OP_START_DATE AND A.START_DATE <= P.OP_END_DATE AND A.START_DATE >= P.OP_START_DATE AND A.START_DATE <= P.OP_END_DATE ) cc +GROUP BY cc.person_id, cc.event_id +HAVING COUNT(cc.event_id) >= 1 -- End Correlated Criteria ) CQ on E.person_id = CQ.person_id and E.event_id = CQ.event_id @@ -131,8 +127,9 @@ TRUNCATE TABLE #Inclusion_0; DROP TABLE #Inclusion_0; -with cteIncludedEvents(event_id, person_id, start_date, end_date, op_start_date, op_end_date, ordinal) as -( +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 ( @@ -141,14 +138,11 @@ with cteIncludedEvents(event_id, person_id, start_date, end_date, op_start_date, 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 - +{1 != 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),1)-1) - -) -select event_id, person_id, start_date, end_date, op_start_date, op_end_date -into #included_events -FROM cteIncludedEvents Results +} +) Results ; @@ -161,14 +155,14 @@ with ctePersons(person_id) as ( 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 + 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 = 4 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 + 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 = 4 AND de.drug_source_concept_id = cs.concept_id @@ -180,38 +174,20 @@ 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 ROWS UNBOUNDED PRECEDING) AS start_ordinal, - ROW_NUMBER() OVER (PARTITION BY PERSON_ID ORDER BY EVENT_DATE, EVENT_TYPE) 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 + + select person_id, min(start_date) as era_start_date, DATEADD(day,-1 * 30, max(end_date)) as era_end_date + from ( + select person_id, start_date, end_date, sum(is_start) over (partition by person_id order by start_date, is_start desc rows unbounded preceding) group_idx + from ( + select person_id, start_date, end_date, + case when max(end_date) over (partition by person_id order by start_date rows between unbounded preceding and 1 preceding) >= start_date then 0 else 1 end is_start + from ( + select person_id, drug_exposure_start_date as start_date, DATEADD(day,(30 + 0),DRUG_EXPOSURE_END_DATE) as end_date + FROM #drugTarget + ) DT + ) ST + ) GR + group by person_id, group_idx ) ERAS on ERAS.person_id = et.person_id WHERE et.start_date between ERAS.era_start_date and ERAS.era_end_date; @@ -220,80 +196,41 @@ DROP TABLE #drugTarget; -- generate cohort periods into #final_cohort -with cohort_ends (event_id, person_id, end_date) as -( - -- cohort exit dates - -- By default, cohort exit at the event's op end date +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 -), -first_ends (person_id, start_date, end_date) as -( - select F.person_id, F.start_date, F.end_date - FROM ( - select I.event_id, I.person_id, I.start_date, E.end_date, row_number() over (partition by I.person_id, I.event_id order by E.end_date) as ordinal - from #included_events I - join cohort_ends E on I.event_id = E.event_id and I.person_id = E.person_id and E.end_date >= I.start_date + ) 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 -) -select person_id, start_date, end_date -INTO #cohort_rows -from first_ends; - -with cteEndDates (person_id, end_date) AS -- the magic -( - SELECT - person_id - , DATEADD(day,-1 * 0, event_date) as end_date - FROM - ( - SELECT - person_id - , event_date - , event_type - , MAX(start_ordinal) OVER (PARTITION BY person_id ORDER BY event_date, event_type ROWS UNBOUNDED PRECEDING) AS start_ordinal - , ROW_NUMBER() OVER (PARTITION BY person_id ORDER BY event_date, event_type) AS overall_ord - FROM - ( - SELECT - person_id - , start_date AS event_date - , -1 AS event_type - , ROW_NUMBER() OVER (PARTITION BY person_id ORDER BY start_date) AS start_ordinal - FROM #cohort_rows - - UNION ALL - - - SELECT - person_id - , DATEADD(day,0,end_date) as end_date - , 1 AS event_type - , NULL - FROM #cohort_rows - ) RAWDATA - ) e - WHERE (2 * e.start_ordinal) - e.overall_ord = 0 -), -cteEnds (person_id, start_date, end_date) AS -( - SELECT - c.person_id - , c.start_date - , MIN(e.end_date) AS end_date - FROM #cohort_rows c - JOIN cteEndDates e ON c.person_id = e.person_id AND e.end_date >= c.start_date - GROUP BY c.person_id, c.start_date -) -select person_id, min(start_date) as start_date, end_date +) FE; + + +select person_id, min(start_date) as start_date, DATEADD(day,-1 * 0, max(end_date)) as end_date into #final_cohort -from cteEnds -group by person_id, end_date -; +from ( + select person_id, start_date, end_date, sum(is_start) over (partition by person_id order by start_date, is_start desc rows unbounded preceding) group_idx + from ( + select person_id, start_date, end_date, + case when max(end_date) over (partition by person_id order by start_date rows between unbounded preceding and 1 preceding) >= start_date then 0 else 1 end is_start + from ( + select person_id, start_date, DATEADD(day,0,end_date) as end_date + from #cohort_rows + ) CR + ) ST +) GR +group by person_id, group_idx; 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) @@ -301,7 +238,148 @@ select @target_cohort_id as cohort_definition_id, person_id, start_date, end_dat 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 & 1 != 0}?{ + +-- Create a temp table of inclusion rule rows for joining in the inclusion rule impact analysis + +select cast(rule_sequence as int) as rule_sequence +into #inclusion_rules +from ( + SELECT CAST(0 as int) as rule_sequence +) IR; + + +-- 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; @@ -324,4 +402,3 @@ DROP TABLE #included_events; TRUNCATE TABLE #Codesets; DROP TABLE #Codesets; -