Thread: Query help...

Query help...

From
Joshua Adam Ginsberg
Date:
A simplified version of my situation...

I've got three tables that I'm working with... the first is a table of
staff members... firstname, lastname, staffid... nothing tough... the
second is a table of jobs... job title, jobid... nothing tough... the
third is a history of job assignments... it's got a staffid, a jobid, a
timestamp, and a field to denote whether the job was added or dropped...
this third table exists because it is useful in this project to be able
to look at a staff member's job history...

The problem I'm running into is queries that attempt to determine who is
an "active" member of the staff, defined as a staff member who currently
has at least one job added but not dropped... this can be easily
measured by saying that if the number of times a staff member had a job
added is greater than the number of times that same staff member had a
job dropped, that staff member is active...

What I'm having trouble figuring out is how can I incorporate those
rowcounts into a greater query...

I've succeeded in some other cases... I can get a list of the active
personnel:

select staff.staff_id, firstnames, lastname, jobs.job_id, job_title from
staff, staff_history, jobs where staff.staff_id = staff+history.staff_id
and jobs.job_id = staff_history.job_id group by staff.staff_id,
firstnames, lastname, jobs.job_id, job_title having (count(add_or_drop)
% 2) = 1 order by lastname, firstnames;

This succeeds because for each person-job combination, if there's 0 mod
2 instances of them, then the person has added and dropped the job (some
number of times)... if there's 1 mod 2 instances, then the person has
added but not dropped the job...

I can get a list of jobs and who is actively assigned to the job:

select jobs.job_id, job_title, staff.staff_id, firstnames, lastname from
jobs left outer join (staff_history join staff on
(staff_history.staff_id = staff.staff_id)) on (jobs.job_id =
staff_history.job_id) group by jobs.job_id, staff.staff_id, job_title,
firstnames, lastname having (count(staff.staff_id) % 2 = 1);

This succeeds because for each grouping, which again is a person-job
combination, I can eliminate anybody who has been assigned and
deassigned to the same job the same number of times...

But here's a case where I can't figure it out... I'm trying to generate
a list of staff members with the "active" staff members first... now, I
can't use my same of mod 2 here, because a person can have more than one
job... so if i have been added to two jobs but not removed from any,
count(add_or_drop) % 2 = 0, but I am active...

Any suggestions?

-jag


--
--------------------------------------------------------
Joshua Ginsberg                 rainman@owlnet.rice.edu
Director of Technology          dirtech@sa.rice.edu
Student Association             AIM: L0stInTheDesert
Rice University, Houston, TX
========================================================
"Programming today is a race between software engineers
striving to build bigger and better idiot-proof programs
and the Universe trying to produce bigger and better
idiots. So far, the Universe is winning." -Rich Cook
--------------------------------------------------------


Re: Query help...

From
Thomas Lockhart
Date:
> I've got three tables that I'm working with... the first is a table of
> staff members... firstname, lastname, staffid... nothing tough... the
> second is a table of jobs... job title, jobid... nothing tough... the
> third is a history of job assignments... it's got a staffid, a jobid, a
> timestamp, and a field to denote whether the job was added or dropped...
> this third table exists because it is useful in this project to be able
> to look at a staff member's job history...
...
> Any suggestions?

Perhaps not a helpful one... but I would be inclined to reorganize that
third table to have a "start date" *and* a "stop date" field, and ditch
the "dropped" boolean:

o it would keep you from having to figure out how to associate two
entries in the same table with the same job (the added and dropped
rows). How would you currently prevent a job from being entered as
"dropped" without a corresponding "added" row?

o it would make it easier to do the query you are asking about; to tell
whether someone has an active job, just select on a date -- like 'today'
-- between the start and stop dates.

o it may better match reality; jobs have a duration so represent that
explicitly.

hth

                       - Thomas

Re: Query help...

From
Andrew Gould
Date:
Have you thought about adding an integer field (we'll
call it 'status')that is dependent upon the
add_or_drop filed?  (I'm assuming that add_or_drop has
a not null constraint and must have either 'add' or
'drop'.)

Before running report queries run:

update staff_history
set add_drop_status = case when add_or_drop='add' then
1 else -1 end;

The following query should give you a list of active
staff/job combinations:

select staff_id, job_id, max(date_filed) as eff_date,
sum(add_drop_status) as status from staff_history
group by staffid, job_id having sum(add_drop_status) >
0;

Of course, if you just change add_or_drop to the
status field, you can eliminate the update step.

I hope this helps.

Andrew Gould

--- Joshua Adam Ginsberg <rainman@owlnet.rice.edu>
wrote:
> A simplified version of my situation...
>
> I've got three tables that I'm working with... the
> first is a table of
> staff members... firstname, lastname, staffid...
> nothing tough... the
> second is a table of jobs... job title, jobid...
> nothing tough... the
> third is a history of job assignments... it's got a
> staffid, a jobid, a
> timestamp, and a field to denote whether the job was
> added or dropped...
> this third table exists because it is useful in this
> project to be able
> to look at a staff member's job history...
>
> The problem I'm running into is queries that attempt
> to determine who is
> an "active" member of the staff, defined as a staff
> member who currently
> has at least one job added but not dropped... this
> can be easily
> measured by saying that if the number of times a
> staff member had a job
> added is greater than the number of times that same
> staff member had a
> job dropped, that staff member is active...
>
> What I'm having trouble figuring out is how can I
> incorporate those
> rowcounts into a greater query...
>
> I've succeeded in some other cases... I can get a
> list of the active
> personnel:
>
> select staff.staff_id, firstnames, lastname,
> jobs.job_id, job_title from
> staff, staff_history, jobs where staff.staff_id =
> staff+history.staff_id
> and jobs.job_id = staff_history.job_id group by
> staff.staff_id,
> firstnames, lastname, jobs.job_id, job_title having
> (count(add_or_drop)
> % 2) = 1 order by lastname, firstnames;
>
> This succeeds because for each person-job
> combination, if there's 0 mod
> 2 instances of them, then the person has added and
> dropped the job (some
> number of times)... if there's 1 mod 2 instances,
> then the person has
> added but not dropped the job...
>
> I can get a list of jobs and who is actively
> assigned to the job:
>
> select jobs.job_id, job_title, staff.staff_id,
> firstnames, lastname from
> jobs left outer join (staff_history join staff on
> (staff_history.staff_id = staff.staff_id)) on
> (jobs.job_id =
> staff_history.job_id) group by jobs.job_id,
> staff.staff_id, job_title,
> firstnames, lastname having (count(staff.staff_id) %
> 2 = 1);
>
> This succeeds because for each grouping, which again
> is a person-job
> combination, I can eliminate anybody who has been
> assigned and
> deassigned to the same job the same number of
> times...
>
> But here's a case where I can't figure it out... I'm
> trying to generate
> a list of staff members with the "active" staff
> members first... now, I
> can't use my same of mod 2 here, because a person
> can have more than one
> job... so if i have been added to two jobs but not
> removed from any,
> count(add_or_drop) % 2 = 0, but I am active...
>
> Any suggestions?
>
> -jag
>
>
> --
>
--------------------------------------------------------
> Joshua Ginsberg
> rainman@owlnet.rice.edu
> Director of Technology          dirtech@sa.rice.edu
> Student Association             AIM: L0stInTheDesert
> Rice University, Houston, TX
>
========================================================
> "Programming today is a race between software
> engineers
> striving to build bigger and better idiot-proof
> programs
> and the Universe trying to produce bigger and better
> idiots. So far, the Universe is winning." -Rich Cook
>
--------------------------------------------------------
>
>
> ---------------------------(end of
> broadcast)---------------------------
> TIP 6: Have you searched our list archives?
>
> http://www.postgresql.org/search.mpl


__________________________________________________
Do You Yahoo!?
Send instant messages & get email alerts with Yahoo! Messenger.
http://im.yahoo.com/

Re: Query help...

From
Andrew Gould
Date:
I like Thomas's idea better than the one I just
posted.

If jobs are one-time projects, I would also create a
unique index on staff_history(staff_id, job_id).  This
would help keep the data clean.  (This would not work
if jobs are employment positions or projects that an
employee can leave and return to.)

Andrew Gould


--- Thomas Lockhart <lockhart@fourpalms.org> wrote:
> > I've got three tables that I'm working with... the
> first is a table of
> > staff members... firstname, lastname, staffid...
> nothing tough... the
> > second is a table of jobs... job title, jobid...
> nothing tough... the
> > third is a history of job assignments... it's got
> a staffid, a jobid, a
> > timestamp, and a field to denote whether the job
> was added or dropped...
> > this third table exists because it is useful in
> this project to be able
> > to look at a staff member's job history...
> ...
> > Any suggestions?
>
> Perhaps not a helpful one... but I would be inclined
> to reorganize that
> third table to have a "start date" *and* a "stop
> date" field, and ditch
> the "dropped" boolean:
>
> o it would keep you from having to figure out how to
> associate two
> entries in the same table with the same job (the
> added and dropped
> rows). How would you currently prevent a job from
> being entered as
> "dropped" without a corresponding "added" row?
>
> o it would make it easier to do the query you are
> asking about; to tell
> whether someone has an active job, just select on a
> date -- like 'today'
> -- between the start and stop dates.
>
> o it may better match reality; jobs have a duration
> so represent that
> explicitly.
>
> hth
>
>                        - Thomas
>
> ---------------------------(end of
> broadcast)---------------------------
> TIP 1: subscribe and unsubscribe commands go to
majordomo@postgresql.org


__________________________________________________
Do You Yahoo!?
Send instant messages & get email alerts with Yahoo! Messenger.
http://im.yahoo.com/

Re: Query help...

From
missive@frontiernet.net (Lee Harr)
Date:
On Sat, 11 Aug 2001 16:57:10 +0000 (UTC), <lockhart@fourpalms.org>:
> Perhaps not a helpful one... but I would be inclined to reorganize that
> third table to have a "start date" *and* a "stop date" field, and ditch
> the "dropped" boolean:
>

This is how I would do it, then query for employees with
records that have NULL in the "stop date" field.