multiple actions in union query

R

Rob S

I probably am misreading some of what I am reading on union queries, but I
think I can still do what I was wanting to do...with some help.

I have two tables with identical fields, but each is filled in differently
based on how I access the table. Tables are as follows:

TblProgramResourceDistribution
ProgramResourceDistribID
ProgramNameID (drop-down list of member agencies)
Date
ResourcesID (drop-down list of brochures/resources)
QtySent
Program
OtherAgency
AgencyName (not used)
TrainingID

TblOtherOrgResourceDistribution
ProgramResourceDistribID
ProgramNameID (not used)
Date
ResourcesID
QtySent
Program
OtherAgency
AgencyName
TrainingID

The goal is to track the total number of brochures sent to member
organizations and to non-member organizations by brochure name for a given
time period. I understand that a union query requires the data to be the
same. I'm not certain if that means I have to have the same fields all the
way across in both tables or if it simply means that I need to make certain
both tables have the ResourcesID and QtySent fields and the rest don't
really matter.

I have a form where I enter the start and end date and then I use the
following code in other queries to pull the dates over:
Between [Forms]![Reports_Main]![txtStart] And
[forms]![Reports_Main]![txtEnd]

A button on that same page is used to open the report & associated query.

So what i am trying to do is create a union query that pulls the date
requirements from my "main report form" with the click of a button and that
will then sum each type of brochure that was distributed and combine the
results from both tables.

I thought an easier way of doing this would be to use one table with all of
the required fields and two forms that accessed different fields, for
instance if I was entering data for a member organization I would not see
the "OtherAgency' and "AgencyName" fields. Program and OtherAgency are
yes/no fields and would be turned on or off automatically depending on
whether I access a form for member organizations or one for non-member
agencies. Likewise, if i was entering data for brochures sent to a
non-member organization i would not see "Program". But when I try to hide a
field in one form it seems to hide the field in the other form as well.

Any thoughts or suggestions would be appreciated. I've written union
queries before, but never ones that looked for data between specific dates,
grouped the data, and summed the data all at once.

Thanks in advance.
 
T

Tom van Stiphout

In a union query you need to have the same number of columns with the
same data types. They do not have to have the same names.
The where clause in a union query goes over the union (if that makes
sense), so Jet will first put the two sets together, then apply the
filter.

With union queries you often want to know if a particular row came
from table1 or table2. I typically add an extra column:
select "table1", field1, field2 from table1
union
select "table2", field1, field2 from table2

I am very concerned about your database design. There should likely
not be two almost-identical tables, and each table seems a hodge-podge
of several entities. Access is not Excel on steroids.

-Tom.
Microsoft Access MVP

I probably am misreading some of what I am reading on union queries, but I
think I can still do what I was wanting to do...with some help.

I have two tables with identical fields, but each is filled in differently
based on how I access the table. Tables are as follows:

TblProgramResourceDistribution
ProgramResourceDistribID
ProgramNameID (drop-down list of member agencies)
Date
ResourcesID (drop-down list of brochures/resources)
QtySent
Program
OtherAgency
AgencyName (not used)
TrainingID

TblOtherOrgResourceDistribution
ProgramResourceDistribID
ProgramNameID (not used)
Date
ResourcesID
QtySent
Program
OtherAgency
AgencyName
TrainingID

The goal is to track the total number of brochures sent to member
organizations and to non-member organizations by brochure name for a given
time period. I understand that a union query requires the data to be the
same. I'm not certain if that means I have to have the same fields all the
way across in both tables or if it simply means that I need to make certain
both tables have the ResourcesID and QtySent fields and the rest don't
really matter.

I have a form where I enter the start and end date and then I use the
following code in other queries to pull the dates over:
Between [Forms]![Reports_Main]![txtStart] And
[forms]![Reports_Main]![txtEnd]

A button on that same page is used to open the report & associated query.

So what i am trying to do is create a union query that pulls the date
requirements from my "main report form" with the click of a button and that
will then sum each type of brochure that was distributed and combine the
results from both tables.

I thought an easier way of doing this would be to use one table with all of
the required fields and two forms that accessed different fields, for
instance if I was entering data for a member organization I would not see
the "OtherAgency' and "AgencyName" fields. Program and OtherAgency are
yes/no fields and would be turned on or off automatically depending on
whether I access a form for member organizations or one for non-member
agencies. Likewise, if i was entering data for brochures sent to a
non-member organization i would not see "Program". But when I try to hide a
field in one form it seems to hide the field in the other form as well.

Any thoughts or suggestions would be appreciated. I've written union
queries before, but never ones that looked for data between specific dates,
grouped the data, and summed the data all at once.

Thanks in advance.
 
J

John W. Vinson

The where clause in a union query goes over the union (if that makes
sense), so Jet will first put the two sets together, then apply the
filter.

That's certainly true of the ORDER BY clause - there can only be one ORDER BY,
in the last SELECT - but is it in fact true of the WHERE clause? I've always
assumed that each SELECT has its own independent WHERE clause; e.g. in a
Normalizing Union Query you can

SELECT ID, 1 AS MonthNo, [Jan] AS Amount
FROM wideflat WHERE [Jan] IS NOT NULL
UNION ALL
SELECT ID, 2 AS MonthNo, [Feb] AS Amount
FROM wideflat WHERE [Feb] IS NOT NULL
UNION ALL
SELECT ID, 3 AS MonthNo, [Mar] AS Amount
FROM wideflat WHERE [Mar] IS NOT NULL
UNION ALL...


This has independent WHERE clauses for each set.
 
R

Rob S

Thanks for the comments. Ken, you ask about the business model. I don't
know if this is what you are looking for, but let me try to explain a little
bit more. We are a nonprofit organization funded by a number of federal
grants. Because we are grant funded we have to track what is going on and
submit the info back to the federal gov't. We are kind of an umbrella
organization whose membership consists of other organizations. Our primary
purpose is to provide support, training and resources to our member
organizations, but we also provide these same services to non-member
organizations.

In the past we used two separate access db's to track our activities. One
had a table and related form for entry of "technical assistance" (ta)
support to member programs, a table for ta to non-member programs, a table
for resource distributions for member programs, another for resource
distributions to non-member programs and then another table for "mailings".
The second db was used to track meetings, trainings conducted and trainings
attended. Staff were very frustrated because they often had to enter
similar data several times in order to get the full picture. For instance,
someone might receive a phone call from a member program requesting
assistance with a particular issue and during the phone call also request 50
brochures which are sent out later that day. This would require entering
the date, staff person, and name of the organization in three different
screens. Another example was if we had a new brochure come in that is sent
out to all of our member organizations, the exact same data would have to be
entered for each.

My goal was to streamline the databases and actually combine them into one
database, making data entry easier and since we are a nonprofit doing all of
this on my own to avoid increased costs. I am using subforms that pull info
from the parent form to make data entry easier. For example, when a new
brochure is added and sent out to all of our agencies the parent form would
ask for the date, the staff name, and the name of the brochure. The child
form then would autopopulate those entries and all that the user had to
enter in the child form was the name of the organization and the quantity
sent. Similarly, if one program ordered 10 different brochures the user
could go to a screen that had a parent form asking for the date, staff name,
and organization name. The child form would then ask for the names of the
brochures and the quantities of each, again autopopulating the date,
organization name and staff member name. there are a number of places I
have used parent/child forms to make data entry simpler that are similar to
these examples.

Then at the end of a reporting period the db would generate a report showing
how many "ta" calls were received, how many brochures were sent out, how
many people were trained, the types of people by profession who attended
trainings, etc. On the original question, we would like to be able to look
at a couple of different items. First we would like to be able to see which
member organization is using the most brochures. Secondly, we would also
like to be able to report that we used 640 of x brochure during the last six
months without paying attention to who actually received them. The union
query was suppose to pull the data from both tables and combine it to show
the total number of each brochure sent out.

If I did use one table as you suggest with a separate form for entering data
on a member organization and another for non-member organizations, how do I
get it to set a value that can allow me to look at activity for non-members
and another for members? Is it a form of an "if" statement? If program
name is null then it must be a non-member, but if program name is not null
then it must be a member organization? Obviously that is laymens language.
That's the part I couldn't figure out and why I went to two separate tables,
which is similar to the original db design that someone else did years ago.

Oh, and yes, the ResourcesID looks up another table to find the names of the
brochures currently being produced. That table has two columns, an id
column and a title column. I use the following code so that the drop-down
list shows the name rather than the id number. SELECT
[Resources].[ResourcesID], [Resources].[Resource] FROM Resources;

unfortunately I'm not a programmer. I've learned what I know by reading
books on access and browsing the internet. I'm not certain if what I'm
doing is what was described as excel on steroids. Not certain what was
meant by that statement. And yes, i do understand that one should avoid
"date" as a field name.

Robert

KenSheridan via AccessMonster.com said:
As your tables mirror each other you can return a single result table with
a
UNION ALL operation like so:

SELECT *,
"Program Resource Distribution" AS DistributionType
FROM
TblProgramResourceDistribution
UNION ALL
SELECT *,
"Other Organisations Distribution"
FROM
TblOtherOrgResourceDistribution;

Save this query as qryAllDistribtions say. This will give you a general
purpose result set which you can use whenever you need to return combined
data from both tables. For your current requirement you can base another
query on this.

As your ResourcesID column appears to be a foreign key I assume you have
another table such as Resources containing the brochure titles in a text
column e.g. ResourceTitle, so the final query would join this to the above
query, group by ResourceTitle and sum the quantities sent, e.g.

PARAMETERS
[Forms]![Reports_Main]![txtStart] DATETIME,
[Forms]![Reports_Main]![txtEnd] DATETIME;
SELECT ResourceTitle, SUM(QtySent) AS NumberDistributed
FROM Resources INNER JOIN qryAllDistribtions
ON Resources.ResourceID = qryAllDistribtions ResourceID
WHERE [Date] BETWEEN [Forms]![Reports_Main]![txtStart]
AND [forms]![Reports_Main]![txtEnd]
GROUP BY ResourceTitle;

Note that the parameters are declared. This is always a good idea with
date/time parameters as they might otherwise be interpreted by Access as
arithmetic expressions and give the wrong results.

You may already be seeing the ResourceTitle values in the ResourceID
column
if its DisplayControl property has been set to a combo box and/or you've
used
the 'lookup wizard' when setting the column's data type in the original
tables' design. If so this is not really a good idea. For reasons why
see:

http://www.mvps.org/access/lookupfields.htm

Even if you are seeing the text values in this column you should
nevertheless
join the tables in a query as above. In a form you can use a combo box
bound
to the ResourceID column to select from the text values. The combo box
wizard can create this for you, though its not difficult to hand-craft it.

Another point worth mentioning is that Date is not a good choice for a
column
name as it’s the name of a built in function (returning the current date),
so
like all 'reserved words' should be avoided as an object name. Something
like DistributionDate would be better. If you do use date be sure to warp
it
in square brackets when referencing it in a query or code.

You were quite right that a single table would be better, either adding a
DistributionType (or whatever) column to distinguish between rows for
members
and others, or including a MemberOrganization Boolean (Yes/No) column
whose
value would be set to TRUE for the member rows, FALSE for the others. You
can easily fill such a table from your existing two with a couple of
'append'
queries.

With a single table as above, rather than hiding/showing controls, you can
then have two separate forms, one for members one for others each based on
a
query which returns the 'member' rows, the other which returns the 'other'
rows. In each form include controls bound only to the relevant columns
and
set the DefaultValue property of the DistributionType or
MemberOrganization
control to the appropriate value for the form in question so that the
value
is automatically inserted when adding a new record.

As Tom points out, your table structure suggests that there may be other
design issues, but without more details of your business model we can't be
categorical about this.

Ken Sheridan
Stafford, England

Rob said:
I probably am misreading some of what I am reading on union queries, but I
think I can still do what I was wanting to do...with some help.

I have two tables with identical fields, but each is filled in differently
based on how I access the table. Tables are as follows:

TblProgramResourceDistribution
ProgramResourceDistribID
ProgramNameID (drop-down list of member agencies)
Date
ResourcesID (drop-down list of brochures/resources)
QtySent
Program
OtherAgency
AgencyName (not used)
TrainingID

TblOtherOrgResourceDistribution
ProgramResourceDistribID
ProgramNameID (not used)
Date
ResourcesID
QtySent
Program
OtherAgency
AgencyName
TrainingID

The goal is to track the total number of brochures sent to member
organizations and to non-member organizations by brochure name for a given
time period. I understand that a union query requires the data to be the
same. I'm not certain if that means I have to have the same fields all
the
way across in both tables or if it simply means that I need to make
certain
both tables have the ResourcesID and QtySent fields and the rest don't
really matter.

I have a form where I enter the start and end date and then I use the
following code in other queries to pull the dates over:
Between [Forms]![Reports_Main]![txtStart] And
[forms]![Reports_Main]![txtEnd]

A button on that same page is used to open the report & associated query.

So what i am trying to do is create a union query that pulls the date
requirements from my "main report form" with the click of a button and
that
will then sum each type of brochure that was distributed and combine the
results from both tables.

I thought an easier way of doing this would be to use one table with all
of
the required fields and two forms that accessed different fields, for
instance if I was entering data for a member organization I would not see
the "OtherAgency' and "AgencyName" fields. Program and OtherAgency are
yes/no fields and would be turned on or off automatically depending on
whether I access a form for member organizations or one for non-member
agencies. Likewise, if i was entering data for brochures sent to a
non-member organization i would not see "Program". But when I try to hide
a
field in one form it seems to hide the field in the other form as well.

Any thoughts or suggestions would be appreciated. I've written union
queries before, but never ones that looked for data between specific
dates,
grouped the data, and summed the data all at once.

Thanks in advance.
 
R

Rob S

Ken,

Thanks for the explanation. There is a lot to think through here and I
appreciate it. Like I said before, I'm self-taught, but evidently not very
well. I need to think through a lot of what you have said here and see if
there are things that I can do to make this work better. I guess one
problem of looking at what someone else has done, and trying to model their
work is if they didn't do it correctly to begin with then you are likely
only going to exacerbate the problems later on.

You ask about my use of forms and subforms and my use of the term
"autopopulating". I think in reading your response you would say my db is
filled with problems. Going back to my example of a staff member (someone
that works in our office) responding to a request for different brochures.
The parent form had a place for the staff member to fill in the date, his or
her name, and the name of the organization receiving the brochures. The
child form is a form that links to a table with date, staff and program in
it, as well as the name of the brochures and the quantity sent. The child
form would pull the date, staff and organization name from the parent form
and put that data into the child form in fields that were hidden. Then all
the user had to do was input the brochure name and quantity without having
to re-enter the date, time and program name. My assumption with this model
was that when running a report I would not have to build a complex query,
that everything I was looking for (date as basis of query, brochure as
grouping of query and quantity as sum of query) is contained in one table
completed by the child form.

I should make one clarification that may or may not make a difference in
your discription. The member organizations are a set group. Thus I created
a table with each organization listed. The non-member organizations are
undetermined. We might get a request for a brochure from someone and never
hear from them again, or we might work with them on a regular basis even
though they are not a member organization. the member organizations seem to
allow for the use of a look-up table operation while the non-member
organizations are best suited for a text entry. I suppose the alternative
is that they are all on a look-up table and if we are providing something to
someone that is a non-member organization and not already in the table there
is a "button" that adds them to the look-up table. In my mind this seems a
bit cumbersome, but maybe that is the best method for the computer.

I do appreciate the time you spent in answering my question, I was not
expecting that much input. It is greatly appreciated and while not fully
understood it gives me somethings to think about and do some background info
to do some follow-up research with so that i hopefully can fully grasp
everything you wrote.

Robert


KenSheridan via AccessMonster.com said:
Robert:

Firstly I should stress that the UNION operation I described will work
with
your present tables, so while there may be scope for improvement of the
model,
and this would be desirable, it is not an absolute requirement

I'll start at the end with what is meant by Tom's phrase 'Excel on
steroids',
which is one you'll see used from time to time in quite a lot of responses
here. What it means is that an Access table is structured more in the way
we'd build a worksheet in Excel rather than a database in Access. The
main
symptoms of this are:

1. Multiple columns are used for different values of the same type of
attribute. Say you had a table of people and the their MS Office software
usage on a scale of 0 to 10, zero meaning they don't use a particular
piece
of software, 10 meaning they are a heavy user, you might in an Excel
worksheet have a column for the person and then separate columns for Word,
Excel, Access, Outlook, PowerPoint etc. with values from 0 to 10 in the
columns. If you reproduce this with a database table this is known as
'encoding data as column headings'. A fundamental principle of the
database
relational model (the Information Principle) is that data is stored as
values
at row positions in tables and in no other way, so this is not how its
done
in a relational database. Instead you'd have a table for People with one
row
for each, a table for Software with one row for each and a table for
SofwareUsed with columns PersonID, SoftwareID and Usage. So if a person
whose PersonID is 42 uses Access whose SoftwareID is 3 and their usage is
5
on the scale there would be row:

42 3 5

in the SofwareUsed table.

2. Another common symptom of an inappropriately designed table is that it
contains redundant columns and is consequently not properly 'normalized'.
Say in Excel you have a worksheet of contacts with columns ContactName,
AddressLine1, AddressLine2, City, State, ZipCode you may well think that
an
Access table which mirrors this would be fine, but if we look a little
closer
we'll find that this design allows for inconsistent data because it
includes
a redundant State column.

To understand why its redundant we need to look at what normalization
involves. Normalization is a set of formal 'rules' which, if followed,
eliminate redundancy from a table. There are 5 'normal forms', which in
fact
is 6 because an extra one, Boyce Cod Normal Form, was added when it was
found that the original set didn't cope with a particular situation. For
this example we are particularly interested in Third Normal Form (3NF).
Its
formal definition (taken from Chris Date) is as follows:

Third Normal Form: A relvar is in 3NF if and only if its in 2NF and every
non-
key attribute is non-transitively dependent on the primary key.

Very loosely speaking a table is the equivalent of the term relation, a
table
definition is the equivalent of the term relvar (relation variable), a
column
(aka field) is the equivalent of the term attribute, and a row (aka
record)
is the equivalent of the term tuple in the formal language of the
relational
model.

Informally we can translate this into 'all non-key columns must be
functionally dependent solely on the whole of the table's primary key'.
By
'functionally dependent' is meant that the value of one column is
determined
by the value of another, e.g if I'm the person 42 referred to above then
columns Firstname and Lastname are functionally dependent on PersonID
because
for a PersonID value of 42 the values of Firstname and Lastname can only
be
Ken and Sheridan. This is stored only once in the database, so (unless I
change my name back to its original Irish version of Cináed O'Siridean)
anytime I appear in the database I'm always Ken Sheridan.

Lets consider the Excel worksheet an Access table, and in particular the
columns City and State. If John Doe lives in San Francisco the values in
City and State will be San Francisco and California, but we know San
Francisco is in California, so the State column is functionally dependent
on
the City column. The City column is functionally dependent on the
PersonID
column (correctly), so we have a transitive functional dependency
PersonID---
City---->State and the table is not in 3NF. So what? Well lets say we
add
Jane Doe to the table. She also lives in San Francisco but we are
momentarily distracted by a radio report from Dallas and mistakenly put
Texas
in the Sate column. There is nothing to stop us doing this, so we now
have
inconsistent data and when we search for all people in California we don't
get Jane Doe returned and when we search for all people in Texas we
incorrectly get her returned.

To eliminate the redundancy and the risk of such inconsistencies we
'decompose' the table into three tables, people, Cities and States.
States
has just one column State, which is its primary key of course. Cities has
three columns CityID , City and State of which CityID, an arbitrary unique
number such as an autonumber, is the primary key; this is necessary
because
unlike state names, city names can legitimately be duplicated. People
includes a 'foreign key' City ID column (not an autonumber this time)
which
references the primary key of Cities, so we can distinguish between two
cities of the same name. The tables are now in 3NF and here is no
possibility of the sort of inconsistencies we encountered with the
original
table before decomposition.

You might be wondering why, when the Cities table includes a State column
with the State names, we need a States column at all. There are two
reasons:
(a) by enforcing 'referential integrity 'in the relationship between Sates
and Cities we only enter state names in Cities which are present in
States,
so can prevent invalid sate names being entered; (b) if we have only one
city
in a particular state in the Cities table and then delete that row we no
longer have any record of the existence of that state at all; this is
known
as an 'update anomaly'.

I've spent some time boring you with all this stuff about normalization
and
the like, but that's because everything else really stems from it, so its
essential to have a good grasp of what it all means if we are going to
design
solid databases. Getting the 'logical model' i.e. the schema of tables
and
the relationships between them is the key to a reliable and efficient
database, because it is a model of that part of the real world with which
we
are concerned, and if we get the model right the database will behave in
the
same way as the real world, but if we get it wrong we'll end up jumping
through hoops until the cows come hoe to work around the design flaws.

Looking at this in the context of your business model I'll take your
example
of the process of handling an order for 10mdifferent brochures and look
at
this from square one without reference to your existing tables as I think
this will better enable you to look critically at your table structures
and
se if any amendments to the model are required.

Firstly, what entity types do we have? A table models an entity type so
this
determines what tables we need.

Clearly there is an Organizations entity type so we need a table
Organizations. This will have a primary key, which can be a 'natural key'
e.
g. the organization's name if these are all distinct, or a 'surrogate'
key, e.
g. an autonumber. Many people favour the use of surrogate keys even when
a
natural 'candidate key' is available, but in such a situating the
'candidate
key' column should be indexed uniquely as well as creating the autonumber
primary key. Non-key columns will be the attributes of the organizations,
remembering that each must be functionally dependant solely on the key.
One
attribute will be a column to identify the member and other organizations
of
course.

Next we have an entity type Resources (brochures in this case) so we have
a
table for those, again with a primary key and non-key columns representing
other functionally dependant attributes.

I'm not sure when you refer to 'staff name' whether you are referring to
the
member of your own staff handling the order, or on the other hand it
refers
to a member of the organization's staff. The model will be different for
each, so I'll come back to the latter scenario later. For now assuming
its
your own staff then an Employees table is needed with EmployeeID as the
key
(necessary because names can be legitimately duplicated, even within small
workgroups) and columns for their names and other functionally dependent
attributes.

Now we come to an interesting concept, because the relationship between
Organizations and Resources is a many-to-many one, i.e. an organizations
might make one or more orders for resources, and each resource may be
supplied to one or more organizations. Unlike a one-to-many or a
one-to-one
relationship, a many-to-many relationship is not created directly between
two
or more tables; it is always created by a third table which includes
foreign
key columns referencing the primary keys of the tables in the many-to-many
relationship. But on the assumption in the preceding paragraph then
Employees is also a part of the relationship, so its 3-way (ternary) and
an
EmployeeID foreign key is needed. The ternary many-to-many relationship
has
therefore been resolved into three one-to-many relationships.
Relationships
are in fact a special king of entity type, so as well as modelling the
relationship the table also models an entity type (Orders) and this has
attributes of its own, e.g. the date of the order, the quantity ordered
etc,
so this Orders table will have non-key columns for those attributes too.

Lets look now at the alternative scenario where the staff are the
'contacts'
within the organizations i.e. in this context the 'contact' placing the
order
on behalf of their organisation. The difference this makes to the model
is
that the relationship is not now between Organizations, Staff and
Resources,
but between Contacts, Staff and Resources, so the Orders table would now
include a ContactID foreign key column in place of the OrganizationID
foreign
key column. The Contacts table would have a foreign key OrganizationID
column referencing the key of Organizations, so Orders maps to
Organizations
via the two relationships Orders--->Contacts--->Organizations.

The above represents an analysis only of what tables might be appropriate
in
the context of the tasks you've outlines and there would doubtless be
other
tables and relationships involved in the full model.

When it comes to querying the database, the reports you mention can all
easily be created with your existing table, using the UNION query I
described
as the basis. When it comes to distinguishing between members and others
the
DistibutionType column which the query returns, with the constants
'Program
Resource Distribution' and 'Other Organisations Distribution' allows you
to
do this in any queries based on the UNION query or by the WhereCondition
setting of the OpenReport or OpenForm method if opening a report or form
based on the UNION query (such a form would not be updatable of course).
You
could also do it by testing for 'ProgramName IS NULL' or ''ProgramName IS
NOT
NULL' as you say. Nevertheless having two tables is not a good design as
it
encodes data as table names in this case.

When you describe your forms and subforms, which is certainly the type of
interface called for here regardless of the details of the model, you
refer
to 'autopopulating' the subforms. If by this you mean that the subforms
are
showing data from the parent form's underlying table by virtue of being
based
on a query that includes that table then that's fine. but if you mean that
values from the parent form's underlying table are actually being inserted
into the subform's underlying table, then that is almost certainly a very
bad
design as it means the subform's underlying table contains very high
levels
of redundancy and is consequently exposed to the risk of inconsistent
data.
I said 'almost certainly' here because there are situations when to insert
values from a referenced table into a referencing table is valid. The
classic one is that of an InvoiceDetails table which includes a UnitPrice
column even though a Products table to which a foreign key ProductID
column
in InvoiceDetails refers also includes a UnitPrice column. In this case
the
values in the UnitPrice column in Products will change over time, but you
would want those in the UnitPrice column in InvoiceLines to remain static
at
the value when the invoice was raised. In relational-speak what I'm
saying
here is that UnitPrice in Products is functionally dependent on the key of
Products, but UnitPrice in UnitPrice is functionally dependent on the key
of
InvoiceLines.

How far you want to go in recasting your tables is of course for you to
decide, but hopefully, even if you decide not to try and normalize the
tables
fully then the above will have given you a better understanding of where
any
flaws in the design exist and the possible implications of these in terms
of
the integrity of your data.

Ken Sheridan
Stafford, England

Rob said:
Thanks for the comments. Ken, you ask about the business model. I don't
know if this is what you are looking for, but let me try to explain a
little
bit more. We are a nonprofit organization funded by a number of federal
grants. Because we are grant funded we have to track what is going on and
submit the info back to the federal gov't. We are kind of an umbrella
organization whose membership consists of other organizations. Our
primary
purpose is to provide support, training and resources to our member
organizations, but we also provide these same services to non-member
organizations.

In the past we used two separate access db's to track our activities. One
had a table and related form for entry of "technical assistance" (ta)
support to member programs, a table for ta to non-member programs, a table
for resource distributions for member programs, another for resource
distributions to non-member programs and then another table for
"mailings".
The second db was used to track meetings, trainings conducted and
trainings
attended. Staff were very frustrated because they often had to enter
similar data several times in order to get the full picture. For
instance,
someone might receive a phone call from a member program requesting
assistance with a particular issue and during the phone call also request
50
brochures which are sent out later that day. This would require entering
the date, staff person, and name of the organization in three different
screens. Another example was if we had a new brochure come in that is
sent
out to all of our member organizations, the exact same data would have to
be
entered for each.

My goal was to streamline the databases and actually combine them into one
database, making data entry easier and since we are a nonprofit doing all
of
this on my own to avoid increased costs. I am using subforms that pull
info
from the parent form to make data entry easier. For example, when a new
brochure is added and sent out to all of our agencies the parent form
would
ask for the date, the staff name, and the name of the brochure. The child
form then would autopopulate those entries and all that the user had to
enter in the child form was the name of the organization and the quantity
sent. Similarly, if one program ordered 10 different brochures the user
could go to a screen that had a parent form asking for the date, staff
name,
and organization name. The child form would then ask for the names of the
brochures and the quantities of each, again autopopulating the date,
organization name and staff member name. there are a number of places I
have used parent/child forms to make data entry simpler that are similar
to
these examples.

Then at the end of a reporting period the db would generate a report
showing
how many "ta" calls were received, how many brochures were sent out, how
many people were trained, the types of people by profession who attended
trainings, etc. On the original question, we would like to be able to
look
at a couple of different items. First we would like to be able to see
which
member organization is using the most brochures. Secondly, we would also
like to be able to report that we used 640 of x brochure during the last
six
months without paying attention to who actually received them. The union
query was suppose to pull the data from both tables and combine it to show
the total number of each brochure sent out.

If I did use one table as you suggest with a separate form for entering
data
on a member organization and another for non-member organizations, how do
I
get it to set a value that can allow me to look at activity for
non-members
and another for members? Is it a form of an "if" statement? If program
name is null then it must be a non-member, but if program name is not null
then it must be a member organization? Obviously that is laymens
language.
That's the part I couldn't figure out and why I went to two separate
tables,
which is similar to the original db design that someone else did years
ago.

Oh, and yes, the ResourcesID looks up another table to find the names of
the
brochures currently being produced. That table has two columns, an id
column and a title column. I use the following code so that the drop-down
list shows the name rather than the id number. SELECT
[Resources].[ResourcesID], [Resources].[Resource] FROM Resources;

unfortunately I'm not a programmer. I've learned what I know by reading
books on access and browsing the internet. I'm not certain if what I'm
doing is what was described as excel on steroids. Not certain what was
meant by that statement. And yes, i do understand that one should avoid
"date" as a field name.

Robert
As your tables mirror each other you can return a single result table
with
a
[quoted text clipped - 158 lines]
Thanks in advance.
 
T

Tom van Stiphout

On Sat, 25 Jul 2009 20:07:50 -0600, John W. Vinson

You are correct. I was thinking of the Orderby clause.
-Tom.

The where clause in a union query goes over the union (if that makes
sense), so Jet will first put the two sets together, then apply the
filter.

That's certainly true of the ORDER BY clause - there can only be one ORDER BY,
in the last SELECT - but is it in fact true of the WHERE clause? I've always
assumed that each SELECT has its own independent WHERE clause; e.g. in a
Normalizing Union Query you can

SELECT ID, 1 AS MonthNo, [Jan] AS Amount
FROM wideflat WHERE [Jan] IS NOT NULL
UNION ALL
SELECT ID, 2 AS MonthNo, [Feb] AS Amount
FROM wideflat WHERE [Feb] IS NOT NULL
UNION ALL
SELECT ID, 3 AS MonthNo, [Mar] AS Amount
FROM wideflat WHERE [Mar] IS NOT NULL
UNION ALL...


This has independent WHERE clauses for each set.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Table / organization question 2
UNION QUERY.. 3
Alternative to union query 32
auto fill fields in sub 0
union queries - with tables containing fields with attachments 2
Union query 5
Union Queries 5
Union query 5

Top