Query help...

Started by Joshua Adam Ginsbergover 24 years ago5 messagesgeneral
Jump to latest
#1Joshua Adam Ginsberg
rainman@owlnet.rice.edu

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
--------------------------------------------------------

#2Thomas Lockhart
lockhart@fourpalms.org
In reply to: Joshua Adam Ginsberg (#1)
Re: Query help...

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

#3Andrew Gould
andrewgould@yahoo.com
In reply to: Joshua Adam Ginsberg (#1)
Re: Query help...

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/

#4Andrew Gould
andrewgould@yahoo.com
In reply to: Thomas Lockhart (#2)
Re: Query help...

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/

#5Lee Harr
missive@frontiernet.net
In reply to: Thomas Lockhart (#2)
Re: Query help...

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.