Re: need ``row number`` - Mailing list pgsql-general
From | Karsten Hilbert |
---|---|
Subject | Re: need ``row number`` |
Date | |
Msg-id | 20040924092117.A1195@hermes.hilbert.loc Whole thread Raw |
In response to | Re: need ``row number`` ("Ian Harding" <iharding@tpchd.org>) |
Responses |
Re: need ``row number``
|
List | pgsql-general |
> You are going to need a set returning function. It will have > to look up the expected boosters, the expected time elapsed, > and return them with their sequence numbers if they exists. > There is no easy way to do it in a view that I can think of. I am not convinced I'll need a SRF. I am not trying to calculate something that isn't there yet. I am just trying to join two views appropriately. I might have to employ some variant of Celko's integer helper table but I'm not sure how to proceed. Karsten > <<< Karsten Hilbert <Karsten.Hilbert@gmx.net> 9/23 1:56p >>> > Hello all, > > yes, I know, "row number" isn't a concept that fits into the > relational model and I will only be asking for something > similar. > > explanation (actual views below) > -------------------------------- > > I have a view that holds the vaccinations scheduled for a > patient (v_vaccs_scheduled4pat) depending on what vaccination > regimes that patient is on. There are typically between 1 to 5 > vaccinations per disease (indication/regime) which is expressed > in the vaccination sequence number. Some regimes also have > booster shots scheduled. Those boosters are to be given > regularly after a set interval. Those have the sequence number > field set to NULL. > > There is a second view that lists all the vaccinations > actually given to a patient per regime (v_pat_vacc4ind). > This view has dates when the shot was given but no sequence > number. > > I now want to create a view which correlates the two showing > me which actual vaccination corresponds to which scheduled > vaccination. This is what I cannot get my head wrapped around > although it is probably fairly straightforward. > > The conceptual solution would be to order actual vaccinations > by date per regime and number them (remember the "row number" > in the subject line ?). One would then join on that with the > sequence numbers from the scheduled vaccinations view and treat > any actual vaccinations where "row number" > max(sequence > number) as being boosters (medically this is correct, btw). > Yes, there can and will be several boosters for some regimes. > > raw data > -------- > full schema here: > http://hherb.com/gnumed/schema/ > > full schema defs in CVS here: > http://savannah.gnu.org/cgi-bin/viewcvs/gnumed/gnumed/gnumed/server/sql/gmClinicalViews.sql > > relevant excerpt: > > --- ========================================================== > --- vaccination stuff > --- ----------------------------------------------------- > \unset ON_ERROR_STOP > drop view v_vacc_regimes; > \set ON_ERROR_STOP 1 > > create view v_vacc_regimes as > select > vreg.id as pk_regime, > vind.description as indication, > _(vind.description) as l10n_indication, > vreg.name as regime, > coalesce(vreg.comment, '') as comment, > vreg.fk_indication as pk_indication, > vreg.fk_recommended_by as pk_recommended_by > from > vacc_regime vreg, > vacc_indication vind > where > vreg.fk_indication = vind.id > ; > > comment on view v_vacc_regimes is > 'all vaccination schedules known to the system'; > > --- ----------------------------------------------------- > \unset ON_ERROR_STOP > drop view v_vacc_defs4reg; > \set ON_ERROR_STOP 1 > > create view v_vacc_defs4reg as > select > vreg.id as pk_regime, > vind.description as indication, > _(vind.description) as l10n_indication, > vreg.name as regime, > coalesce(vreg.comment, '') as reg_comment, > vdef.is_booster as is_booster, > vdef.seq_no as vacc_seq_no, > vdef.min_age_due as age_due_min, > vdef.max_age_due as age_due_max, > vdef.min_interval as min_interval, > coalesce(vdef.comment, '') as vacc_comment, > vind.id as pk_indication, > vreg.fk_recommended_by as pk_recommended_by > from > vacc_regime vreg, > vacc_indication vind, > vacc_def vdef > where > vreg.id = vdef.fk_regime > and > vreg.fk_indication = vind.id > order by > indication, > vacc_seq_no > ; > > comment on view v_vacc_defs4reg is > 'vaccination event definitions for all schedules known to the system'; > > --- ----------------------------------------------------- > \unset ON_ERROR_STOP > drop view v_vacc_regs4pat; > \set ON_ERROR_STOP 1 > > create view v_vacc_regs4pat as > select > lp2vr.fk_patient as pk_patient, > vvr.indication as indication, > vvr.l10n_indication as l10n_indication, > vvr.regime as regime, > vvr.comment as comment, > vvr.pk_regime as pk_regime, > vvr.pk_indication as pk_indication, > vvr.pk_recommended_by as pk_recommended_by > from > lnk_pat2vacc_reg lp2vr, > v_vacc_regimes vvr > where > vvr.pk_regime = lp2vr.fk_regime > ; > > comment on view v_vacc_regs4pat is > 'selection of configured vaccination schedules a patient is actually on'; > > --- ----------------------------------------------------- > \unset ON_ERROR_STOP > drop view v_vaccs_scheduled4pat; > \set ON_ERROR_STOP 1 > > create view v_vaccs_scheduled4pat as > select > vvr4p.pk_patient as pk_patient, > vvr4p.indication as indication, > vvr4p.l10n_indication as l10n_indication, > vvr4p.regime as regime, > vvr4p.comment as reg_comment, > vvd4r.is_booster, > vvd4r.vacc_seq_no, > vvd4r.age_due_min, > vvd4r.age_due_max, > vvd4r.min_interval, > vvd4r.vacc_comment as vacc_comment, > vvr4p.pk_regime as pk_regime, > vvr4p.pk_indication as pk_indication, > vvr4p.pk_recommended_by as pk_recommended_by > from > v_vacc_regs4pat vvr4p, > v_vacc_defs4reg vvd4r > where > vvd4r.pk_regime = vvr4p.pk_regime > ; > > comment on view v_vaccs_scheduled4pat is > 'vaccinations scheduled for a patient according > to the vaccination schedules he/she is on'; > > --- ----------------------------------------------------- > \unset ON_ERROR_STOP > drop view v_pat_vacc4ind; > \set ON_ERROR_STOP 1 > > create view v_pat_vacc4ind as > select > v.fk_patient as pk_patient, > v.id as pk_vaccination, > v.clin_when as date, > vind.description as indication, > _(vind.description) as l10n_indication, > vcine.trade_name as vaccine, > vcine.short_name as vaccine_short, > v.batch_no as batch_no, > v.site as site, > coalesce(v.narrative, '') as narrative, > vind.id as pk_indication, > v.fk_provider as pk_provider, > vcine.id as pk_vaccine, > vpep.pk_health_issue as pk_health_issue, > v.fk_episode as pk_episode, > v.fk_encounter as pk_encounter > from > vaccination v, > vaccine vcine, > lnk_vaccine2inds lv2i, > vacc_indication vind, > v_pat_episodes vpep > where > vpep.pk_episode=v.fk_episode > and > v.fk_vaccine = vcine.id > and > lv2i.fk_vaccine = vcine.id > and > lv2i.fk_indication = vind.id > ; > > comment on view v_pat_vacc4ind is > 'vaccinations a patient has actually received for the various indications'; > > --- ----------------------------------------------------- > \unset ON_ERROR_STOP > drop view v_pat_missing_vaccs; > \set ON_ERROR_STOP 1 > > create view v_pat_missing_vaccs as > select > vvs4p.pk_patient, > vvs4p.indication, > vvs4p.l10n_indication, > vvs4p.regime, > vvs4p.reg_comment, > vvs4p.vacc_seq_no as seq_no, > case when vvs4p.age_due_max is null > then (now() + coalesce(vvs4p.min_interval, vvs4p.age_due_min)) > else ((select identity.dob from identity where identity.id=vvs4p.pk_patient) + vvs4p.age_due_max) > end as latest_due, > --- note that ... > --- ... 1) time_left ... > case when vvs4p.age_due_max is null > then coalesce(vvs4p.min_interval, vvs4p.age_due_min) > else (((select identity.dob from identity where identity.id=vvs4p.pk_patient) + vvs4p.age_due_max) - now()) > end as time_left, > --- ... and 2) amount_overdue ... > case when vvs4p.age_due_max is null > then coalesce(vvs4p.min_interval, vvs4p.age_due_min) > else (now() - ((select identity.dob from identity where identity.id=vvs4p.pk_patient) + vvs4p.age_due_max)) > end as amount_overdue, > --- ... are just the inverse of each other > vvs4p.age_due_min, > vvs4p.age_due_max, > vvs4p.min_interval, > vvs4p.vacc_comment, > vvs4p.pk_regime, > vvs4p.pk_indication, > vvs4p.pk_recommended_by > from > v_vaccs_scheduled4pat vvs4p > where > vvs4p.is_booster is false > and > vvs4p.vacc_seq_no > ( > select count(*) > from v_pat_vacc4ind vpv4i > where > vpv4i.pk_patient = vvs4p.pk_patient > and > vpv4i.indication = vvs4p.indication > ) > ; > > comment on view v_pat_missing_vaccs is > 'vaccinations a patient has not been given yet according > to the schedules a patient is on and the previously > received vaccinations'; > > --- ----------------------------------------------------- > \unset ON_ERROR_STOP > drop view v_pat_missing_boosters; > \set ON_ERROR_STOP 1 > > --- FIXME: only list those that DO HAVE a previous vacc (max(date) is not null) > create view v_pat_missing_boosters as > select > vvs4p.pk_patient, > vvs4p.indication, > vvs4p.l10n_indication, > vvs4p.regime, > vvs4p.reg_comment, > vvs4p.vacc_seq_no as seq_no, > coalesce( > ((select max(vpv4i11.date) > from v_pat_vacc4ind vpv4i11 > where > vpv4i11.pk_patient = vvs4p.pk_patient > and > vpv4i11.indication = vvs4p.indication > ) + vvs4p.min_interval), > (now() - '1 day'::interval) > ) as latest_due, > coalesce( > (now() - ( > (select max(vpv4i12.date) > from v_pat_vacc4ind vpv4i12 > where > vpv4i12.pk_patient = vvs4p.pk_patient > and > vpv4i12.indication = vvs4p.indication) + vvs4p.min_interval) > ), > '1 day'::interval > ) as amount_overdue, > vvs4p.age_due_min, > vvs4p.age_due_max, > vvs4p.min_interval, > vvs4p.vacc_comment, > vvs4p.pk_regime, > vvs4p.pk_indication, > vvs4p.pk_recommended_by > from > v_vaccs_scheduled4pat vvs4p > where > vvs4p.is_booster is true > and > vvs4p.min_interval < age ( > (select max(vpv4i13.date) > from v_pat_vacc4ind vpv4i13 > where > vpv4i13.pk_patient = vvs4p.pk_patient > and > vpv4i13.indication = vvs4p.indication > )) > ; > > comment on view v_pat_missing_boosters is > 'boosters a patient has not been given yet according > to the schedules a patient is on and the previously > received vaccinations'; > > > > > Thanks, > > Karsten Hilbert, MD, PhD > GnuMed i18n coordinator > http://www.gnumed.org > -- > GPG key ID E4071346 @ wwwkeys.pgp.net > E167 67FD A291 2BEA 73BD 4537 78B9 A9F9 E407 1346 > > ---------------------------(end of broadcast)--------------------------- > TIP 8: explain analyze is your friend > > > > ---------------------------(end of broadcast)--------------------------- > TIP 8: explain analyze is your friend -- GPG key ID E4071346 @ wwwkeys.pgp.net E167 67FD A291 2BEA 73BD 4537 78B9 A9F9 E407 1346
pgsql-general by date: