I have to change my first question to the following:
I have 3 tables:
Clients,
Gender,
Race
Clients:
ClientID long integer
GenderID long integer
Gender short text
RaceID long integer
Race short text
Gender:
GenderID long integer
Gender short text
Race:
RaceID long integer
Race short text
What should I do in order to be able to modify data in the main table Clients -so they'd be changed according to content in Race / Gender tables
For example:
Gender table:
GenderID Description
1 Male
2 Female
Clients table:
ClientID GenderID Gender DOB
11 2 Female 1/1/1977
12 2 Female 1/2/1970
13 1 Male 1/4/1969
So, if I'd modify for example, ClientID "13" Gender to "Female" instead of the current one "Male", so that the GenderID would be automatically changed to "2"?
(And no other number would be allowed for that GenderID)
Or - if I'd modify ClientID from 1 to 2, I want the Gender to be changed to "Female"
Thank you, again
You should not use both a character-field, Race, and a foreign-key field, RaceID, in your schema design: you should only use the latter, RaceID.
You shouldn't, and-d-d-d, you don't need to.
Your reports and so forth would then be based upon a query which JOINs to all three tables – displaying the Race.Race value ("White") but never the (meaningless ...) RaceID integer.
Your input-fields would be combo-boxes which query (say) the Race table to find possible values, binding on the RaceID field.
The Clients table contains foreign-key numbers which the end-user never actually sees. Queries (and combo-box parameters) are used to reference the corresponding strings.
You should also use Referential Integrity constraints to ensure that Clients.RaceID, if it is not NULL, must be a value in the Race table.
Related
Can someone help me with a little problem. In summary I have a db where you input someones personal details and I have 4 fields I would like VBA to generate automatically. First field is an ID Number field then following that is DateOfBirth and Age fields. They are auto generated from just the ID field. However, to save me time, I want a part of the ID number field to generate whether a person is male or female.
To explain this let me set an example. The ID number is based on South African identification number. It's a 13 digit number e.g. 851205 5205 08 6. The first 6 numbers tells the date of birth (1985/12/05). That part of the number updates my DOB field and then also tells me the persons age with more VBA. Now i want the numbers "5205" to auto generate my gender field whether a person is male or female. Females are assigned numbers in the range 0000-4999 and males from 5000-9999. If you like more detail then please Google 'decoding your South African ID Number'.
So if i should type in that ID number above then it will define the person as a male. Can anyone help me with some VBA?
Thank you
found a solution and it works just the way i want it to:
If (Mid([txtIDnumber].Value, 7, 4) > 4999) Then
Me.cboGender = "MALE"
Else
Me.cboGender = "FEMALE"
End If
Hi I am relooking at the design of my mysql dbase for efficiency..
currently i have 3 tables
tble country :
country id, country name
table state :
state id, state name, country id
table city :
city id, city name, state id
I am thinking whether it is better to have ...
country name instead of country id in table state
state name instead of state id in table city
this is because everywhere in my code i have to run extra queries to convert country id, state id and city id from numbers to alphabets (eg. 1 to USA)... wouldn't it be better to just reference alphabetically.. (less queries)
The whole world has roughly
260 country/regions
5000 states
many many cities
Design varies based on what you need.
1 - For the purpose of tiny storage:
country(id,country)
state(id,state,country_id)
city(id,city,state_id)
2 - For the purpose of quick query:
city(id,city,state,country)
3 - For the purpose of middle way:
country(code,country)
state(code,country) -- you might merge country and state into one table based on code
city(state_code,city)
You might be interested to have a look at the iso codes:
https://en.wikipedia.org/wiki/ISO_3166-1 eg US
https://en.wikipedia.org/wiki/ISO_3166-2 eg US-NY
As a result iso state code contains iso country code.
UPDATE as per more info from you:
If you are designing property websites for USA.
1 - You do not need a country table, most likely all properties are within USA
2 - There are less than 60 states within USA, so you can use enum to save sates. As nearly all of you will understand NY = New York, as a result you do not need a state table.
3 - So you need a city table. As you will use city_id for more than 10,000,000 property records.
usa_cities(
id int PK
state enum('NY', 'LA', ...)
city varchar
...
)
properties(
id int PK
city_id int,
....
)
AS property table is usually very big, you might skip state table, and de-normalize design to speed up query for less joins:
properties (
id int PK,
state enum('NY', 'LA',...)
city varchar
...
)
You might be able to use enum for city as well, I m not sure how many cities in usa, but it is not encouraged at my first thought.
If you want less query there is some technique call denormalization.
You can weight what most important and fit to your need.
for more about demonalization meaning from techopidia and wikipedia
I have a Perl program that queries a MySQL database to bring back results based upon which "report" option a user has selected from a web page.
One of the reports is all occupants of a student housing building who have applied for a parking permit, but who have not yet been given one.
When the students apply for a permit, it records the specifics about their car (make, model, year, color, etc.) in a single table row. Each apartment can have up to three students, and each student may apply for a permit. So an apartment might have 0 permits, or 1, 2, or 3 permits, depending upon how many of them have cars.
What I'd like to be able to do, is execute a MySQL query that will find out how many occupants in each apartment have applied for a parking permit, and then based on the results of that query, find out how many permits have been issued. If the number of permits issued is less than the number of applications, that apartment number should be returned in the result set. It doesn't have to name the specific occupant, just the fact that the apartment has at least one occupant who has applied for a permit, but not yet received one.
So I have two tables, one is called occupant_info and it contains all kinds of info about the occupant, but the relevant fields are:
counter (a unique row id)
parking_permit_1_number
parking_permit_2_number
parking_permit_3_number
When a parking permit has been assigned, it is recorded in the appropriate parking_permit_#_number field (if it's occupant number one's permit, it would be recorded in parking_permit_1_number, etc.).
The second table is called, parking_permits, and contains all of the car/owner specifics (make, model, year, owner, owner address, etc.). It also contains a field which references the counter from the occupant_info table.
So an example would be:
occupant_info table
counter | parking_permit_1_number | parking_permit_2_number | parking_permit_3_number
--------|-------------------------|-------------------------|------------------------
1 | 12345 | | 98765
2 | 43920 | |
3 | 30239 | | 34233
parking_permits table
counter | counter_from_occupant_info | permit_1_name | permit_2_name | permit_3_name
--------|----------------------------|---------------|-----------------|-------------------
1 |2 | David Jones | James Cameron | Michael Smerconish
2 |3 | Bill Epps | Hillary Clinton | Donald Trump
3 |1 | Joanne Miller | | Sridevi Gupta
I want a query that will first look at how many occupants in an apartment have applied for a permit. This is determined by counting the names in the parking_permits table. In that table, row 1 has three names, row 2 has three names, and row 3 has two names. The query should then look at the occupant_info table, and for each counter_from_occupant_info from the parking_permits table, see if the same number of parking permits have been issued. This can be determined by comparing the number of non-blank parking_permit_#_number fields.
Using the data above, the query would see the following :
parking_permit table row 1
Has counter_from_occupant_info equal to "2"
Has three names
The row in occupant_info with counter = "2" has only one permit number issued,
so counter_from_occupant_info 2 from parking_permits should be in the result set.
parking_permit table row 2
Has counter_from_occupant_info equal to "3"
Has three names
The row in occupant_info with counter = "3" has only two permit numbers issued,
so counter_from_occupant_info 3 from parking_permits should be in the result set.
parking_permit table row 3
Has counter_from_occupant_info equal to "1"
Has two names
The row in occupant_info with counter = "1" has two permit numbers issued,
so this row should *not* be in the result set.
I've thought about using if, then, case, when, type logic to do this in one query, but frankly can't wrap my head around how to do so.
I was thinking something like:
SELECT
CASE WHEN ( SELECT counter_from_occupant_info
FROM parking_permits
WHERE parking_permit_1_name != ""
AND parking_permit_2_name != ""
AND parking_permit_3_name != "" ) THEN
IF ( SELECT parking_permit_1_number,
parking_permit_2_number,
parking_permit_3_number
FROM occupant_info
WHERE counter = ***somehow reference counter from above case statement--I don't know how to do this***
But then my head explodes and I realize I don't know what the heck I'm doing.
Any help would be appreciated. :-)
Doug
You have a few problems:
Your occupants table schema is bad. There's worse out there, but it looks like someone that doesn't understand how a database works built this table.
Your permits table is also bad. Same reason.
You have no idea what you are doing (kidding... kidding...)
Problem 1:
Your occupants table should probably be two tables. Because an occupant could have 0-3 permits (possibly more, I can't tell from the sample data) then you need a table for your occupant's attributes (name, height, gender, age, primary smell, favorite color, first rent date, I dunno).
Occupants
OccupantID | favorite TV Show | number of limbs | first name | last name | aptBuilding
And... another table for Relationship between the occupant and the permit:
Occupant_permits
OccupantID | Permit ID | status
Now... an occupant can have as many permits as you can stuff into that table and the relationship between them has a status "Applied for", or "Granted" or "Revoked" or what have you.
Problem 2
Your permit info table is doing double duty as well. It holds the information about a permit (it's name) as well as the relationship to the occupant. Since we already have a relationship to the occupant with the "Occupant_Permits" table above, we just need a permits table to hold attributes of a permit:
Permits
Permit ID | Permit Name | Description | etc..
Problem 3
Now that you have a correct schema where objects are in their own table (Occupant, Permit, Occupant and Permit Relationship) your query to get a list of apartments that have at least one occupant that has applied, but not yet received a permit would be:
SELECT
COUNT(DISTINCT o.AptBuilding)
FROM
occupants as o
INNER JOIN occupants_permit as op
ON o.occupant_id = op.occupant_id
INNER JOIN permits as p
ON op.permit_id = p.permit_id
WHERE
op.Status = "Applied"
That's nice and simple and you aren't relying on CASE or UNION or count comparison or any fancy stuff. Just nice straight joins and a simple WHERE clause. This will be fast to query and there's no funny business.
Because your schema isn't great, in order to get something similar you'll need to make use of either UNION queries to stack your many permit_N_ fields into a single field and run something similar to the above query, or you'll have use a fair amount of CASE/IF statements:
SELECT DISTINCT p.pCounter
FROM
(
SELECT
counter as Ocounter
CASE WHEN parking_permit_1_number IS NOT NULL THEN 1 ELSE 0 END
+
CASE WHEN parking_permit_2_number IS NOT NULL THEN 1 ELSE 0 END
+
CASE WHEN parking_permit_3_number IS NOT NULL THEN 1 ELSE 0 END AS permitCount
FROM occupant_info
) as o
LEFT OUTER JOIN
(
SELECT
counter_from_occupant_info as pCounter
CASE WHEN parking_permit_1_name IS NOT NULL THEN 1 ELSE 0 END
+
CASE WHEN parking_permit_2_name IS NOT NULL THEN 1 ELSE 0 END
+
CASE WHEN parking_permit_3_Name IS NOT NULL THEN 1 ELSE 0 END AS permitPermitCount
) as p ON o.Ocounter = p.Pcounter
WHERE p.permitCounter > o.PermitCount
I'm not 100% convinced that is exactly what you are looking for since your schema is confusing where you have multiple objects in a single table and everything is pivoted, but... it should get you in the ball park.
This will be much slower too. There's intermediate result sets, CASE statements, and math, so don't expect MySQL to spit this out in milliseconds.
I have a tutoring website where teachers list their preferences for the ages of their potential students.
So far, I have broken those ages into the following categories:
0-4, 5-9, 10-14, 15-19, Adults. These categories, I think, represent decent break points for students ages. But no matter -- the real issue is table creation.
I will make a secondary table, teachers_ages, with a foreign key for teacher_id and another column for age. Should I make this column an enum, with the following acceptable choices '0-4' '5-9', '10-14', '15-19', 'Adults'?. Is this somehow bad-practice (to group numbers with words?) Does it violate any database creation norms? Is there a better way to break age groups for use with CRUD?
Update: teachers can choose as many age groups as they want
Typically you would create a lookup table which would list an identifier and the associated value. For example
Lookup table (AgeRange)
ID Min_Age Max_Age Description
1 0 4 "Less than 4"
2 5 9 "5 to 9"
3 10 14 "10 to 14"
4 15 19 "15 to 19"
5 20 1000 "Adults"
Now you can add another table with the teacher id and the age range id. (There can be more than one entry in this table allowing teachers to have any number of preferences.)
When validating you join to this table and look at Min_Age and Max_Age. When reporting you use the Description field.
If each teacher can only choose one age group you do not need to add a second table. Put the age-group field in the teacher table. Set the datatype as varchar and use check constraints for your five choices.
Your approach is a valid way to break groups down into demographics, such as age, income, population, etc.
I am developing an evaluation system for different programs that needs a lot of flexibility. Each program will have different things to track, so I need to store what data points they want to track, and the corresponding data for the person being evaluated on the particular data point. I am guessing several tables are appropriate. Here is a general outline:
Table: accounts
- unique ID assigned to each account. We'll call this 'aid'
Table: users
- each user with unique ID.
Table: evaluation
- each program will enter in the metrics they want to track into this table (i.e attendance)
- column 'aid' will correspond to 'aid' in account table
Table: evaluation_data
- data (i.e attendance) entered into this database
- column 'aid' will correspond to 'aid' in account table
- column 'uid' will correspond to 'uid' in user table
The input form for evaluation_data will be generated from what's in the evaluation table.
This is the only logical way I can think of doing this. Some of these tables will be growing quite large over time. Is this the most optimal way of doing this?
I'm a little confused about how accounts, users and programs all relate to each other and whether or not account and program are the same thing and that you used the terms interchangeably. I'm going to use different terms which are just easier for me to understand.
Say you have a website that allows freelancers to keep track of different projects and they can create their own data to track. (Hope you see the similarity)
Tables...
freelancers
id title etc
projects
id freelancer_id title description etc
data_options
id freelancer_id title
You can even add other columns like data_type and give options like URL, email, text, date, etc which can be used for validation or to help format the input form.
example data:
1 5 Status
2 5 Budget
3 5 Customer
4 99 Job Type
5 99 Deadline
6 102 Price
7 102 Status
8 102 Due By
This display 3 different freelancers tracking data, freelancers with the id's 5, 99, and 102. Deadline and Due By are essentially the same but freelancers can call these whatever they want.
data_values
id project_id option_id option_value
a column freelancer_id as you would be able to to a join and get the freelancer_id from either the project_id or the option_id
example data:
1000 1 2 $250
1001 1 1 Completed
1002 1 3 Martha Hayes
This is only showing information freelancer with the id 5 has input because option_id's 1-3 belong to that user.