Transforming to 3NF - database

I need to reduce a model DB to 3NF. However there is a column in the data thats very ambiguous.
So the database has the following columns. (Apologies for formatting, I did try)
Employer ID | ContractNo | Hours | emp Name | workNo | workLocation
--
123 | A1 | 10 | J Smith | W36 | New York
124 | A1 | 7 | P Jones | W36 | New York
125 | A2 | 9 | R Lewis | W37 | Los Angeles
123 | A2 | 9 | J Smith | W37 | Los Angeles
Each employee has a unique ID, an employee can work at more than 1 location and each location has a unique workNo. I'm just a bit stuck on where to include the ContractNo. There is no indication in the question of what it actually is for.
So my first step was splitting it up into a table with EmployerID, employee Name and hours. And a second table with WorkNo, WorkLocation. But what do I make of that bloody ContractNo?

I expect the contract is likely a separate entity, capturing the nature of the relationship between contractor and contractee.
Image from QuickDBD, where I work.

Related

Using tabs like database tables

I'd like to use sheets like a database, the big question is how I can keep "foreign-key relationship" when removing or adding new entries in one tab?
An example:
Tab (aka "table") with basic personal information "people":
A | B | C | D
First | Last | E-Mail | Relevant
---------------------------------------------------------------
Peter | Parker | peter#parker.net | X
Steven | Mueller | steven.mueller#gmail.com |
Patricia | Doe | pat#pat.com | X
Based on column D ("Relevant"), I create a list of peoples first names in a second tab "info". Using:
=QUERY(people!A:D, "Select A where D='X'")
Which results in
A | B | C | D
First | | |
---------------------------------------------------------
Peter |
Patricia |
I am now adding more information (birth year and city):
A | B | C | D
First | Year | City |
---------------------------------------------------------
Peter | 1990 | New York
Patricia | 1980 | Boston
** so far, so good ** now the issue is, how can I preserve this data, if I add more entries to the "people" list? If I add an X for the person "Steven" in the "people" table:
A | B | C | D
First | Last | E-Mail | Relevant
---------------------------------------------------------------
Peter | Parker | peter#parker.net | X
Steven | Mueller | steven.mueller#gmail.com | X
Patricia | Doe | pat#pat.com | X
The table in the second tab will look like this - so Peter will "become" Patricia (pushing Patricia down).
A | B | C | D
First | Year | City |
---------------------------------------------------------
Peter | 1990 | New York
Steven | 1980 | Boston
Patricia
What is the best way to make this work?
you either need to introduce a system of IDs or have it sorted as it comes so every new entry will be always placed at the bottom. this way you won't disrupt the non-existent (manual) link.

DLOOKUP STRING CRITERA with simple example

I need help with retrieving the last names for the Authors on the Chapters table.
First, to start this example you need two tables:
tblAuthors
ID FirstName LastName
1 Rob Cooper
2 Geoff Griffith
3 Teresa Hennig
4 Jerry Dennison
tblChapters
ID Author
1 Rob
2 Rob
3 Rob
4 Geoff
5 Geoff
6 Teresa
7 Jerry
while the tblChapters table is selected open, I click the create query button.
Then I add the fields ID and Author. To the right of Author I start a builder for my DLOOKUP().
My Dlookup uses strings.
It doesn't work.
Can you help me?
RetrieveLastName: DLookUp("[LastName]","[tblAuthors]","[FirstName]='" & [Author] & "'")
It works when I put for example:
RetrieveLastName: DLookUp("[LastName]","[tblAuthors]","[FirstName]='Teresa'")
but that is not what I want.
Thanks!
I have looked a multiple multiple websites and tried numbers syntaxes.
If I understand your question correctly, you're looking for data like the following (from the table tblChapters):
+----+--------+----------+
| id | Author | LastName |
+----+--------+----------+
| 1 | Rob | Cooper |
| 2 | Rob | Cooper |
| 3 | Rob | Cooper |
| 4 | Geoff | Griffith |
| 5 | Geoff | Griffith |
| 6 | Teresa | Hennig |
| 7 | Jerry | Dennison |
+----+--------+----------+
I would suggest not using a DLookup in a query setting, this will only cause you headaches.
I would suggest you use this SQL:
SELECT tc.id, tc.Author, ta.LastName
FROM tblChapters tc
INNER JOIN tblAuthors ta ON tc.Author = ta.FirstName
ORDER BY tc.ID
If you are very inclined to use the Design View to setup a query in Access, use the following:
Query Design > Use Tables tblChapters and tblAuthors, link on tblChapters.Atuhor = tblAuthors.FirstName
+--------+-------------+-------------+------------+
| Field: | id | Author | Lastname |
+--------+-------------+-------------+------------+
| Table: | tblChapters | tblChapters | tblAuthors |
+--------+-------------+-------------+------------+
SIDE NOTE: This strategy only works in the case where there are no duplicated FirstNames and/or conflicts accross the two tables.

SSRS - filter on expression in report table

Let's say I have a report with following table in the body:
ID | Name | FirstName | GivenCity | RecordedCity | IsCorrectCity
1 | Gates | Bill | London | New York | No
2 | McCain | John | Brussels | Brussels | Yes
3 | Bullock | Lili | London | London | Yes
4 | Bravo | Johnny | Paris | Las Vegas | No
The column IsCorrectCity Basically includes an expression that checkes GivenCity and RecordedCity and returns a No if different or a Yes when equal.
Is it possible to add a report filter on the column IsCorrectCity (and how) so the users will be able to just select all records with No or Yes? I know this can be done with a parameter in the SQL query, but I would like to add it based on the expressions rather then adding more calculations and all to the query.
Here's a tutorial which explains how you can do it
Filtering Data Without Changing Dataset [SSRS]

Store details of a row in an SQLite DB

I would like to know how I can store details of a row efficiently in an SQLite DB.
For example:
Main-Table:
ID | NAME | CITY
1 | Peter | Paris
2 | Sarah | New York
3 | Seth | Chicago
I want to store details about a person in the database but I don't know how I should do that. The problem is that the data could be represented as an Array in a program code but I can't do that in a DB. My though was this one:
table "person_1": (table for storing favorite places in the city)
NAME | ADDRESS
Eiffel Tower | Champ de Mars, 5 Avenue Anatole
Musee du Louvre | Musée du Louvre, 75058 Paris
table "person_2": (same purpose)
NAME | ADDRESS
One World Trade Center | 285 Fulton Street
Statue of Liberty | Liberty Island
And so on with other persons...
Is this the right approach or can I do it more efficiently?
Main-Table which stored peoples like;
id | name | address
1 | Peter | Paris
2 | Sarah | New York
Favorite_Place table for places like;
id | name | address
1 | Eiffel Tower | Champ de Mars, 5 Avenue Anatole
2 | Musee du Louvre | Musée du Louvre, 75058 Paris
and the middle table something like;
person_id | place_id
1 | 1
1 | 2
2 | 1
2 | 2
If you design tables something like that, you aren't store favorite places again and again in favorite_place table.
This is solved by having 2 tables:
Table People:
id | name | city
1 | Peter | Paris
2 | Sarah | New York
Table Favorite Places:
id | person_id | name | address
1 | 1 | Eiffel Tower | Champ de Mars, 5 Avenue Anatole
2 | 1 | Musee du Louvre | Musée du Louvre, 75058 Paris
3 | 2 | One World Trade Center | 285 Fulton Street
This way you can easily select all favorite places belonging to each person.
You can even write queries JOINing two tables:
SELECT p.name, f.name, f.address
FROM people AS p
JOIN favorites AS f ON p.id = f.person_id
and you'll get:
Peter | Eiffel Tower | Champ de Mars, 5 Avenue Anatole
Peter | Musee du Louvre | Musée du Louvre, 75058 Paris
Sarah | One World Trade Center | 285 Fulton Street

Ingredients for drink new table or string in column?

I am thinking about my application and I want to store data about drinks. Now I am thinking what is best that if I save ingredients just as nvarchar column in table with drink or if I create new table with ingredients and create relationship one to many? I want database to be just read-only and I want to have option filter by ingredients. So what´s best way for windows phone (for performance)? And if the new table would be the better choice, I should use EntitySet, EntityRef, am I right? And I would have for every ingredient new row in table? Let´s say I have 100drinks, in average that every drink has 4ingredients so I have in first table 100rows and in second cca 400rows? Thanks for help
Actually, both solutions proposed are wrong. A drink can have many ingredients and an ingredient can be used in many drinks. Hence, we have a many-to-many relationship here. The proper way to model this is the following (I'm adding data for it to be more understandable):
Ingredients (PK: Id)
+----+--------------------+
| Id | Name |
+----+--------------------+
| 1 | Water |
| 2 | Sugar |
| 3 | Coffe |
| 4 | Virgin Islands Tea |
| 5 | Ice |
+----+--------------------+
Drinks (PK: Id)
+----+-------------+
| Id | Name |
+----+-------------+
| 1 | Black Coffe |
| 2 | Tea |
| 3 | Ice Tea |
+----+-------------+
Drinks_Ingredients (PK: Drink_Id, Ingredient_Id)
+----------+---------------+------------+
| Drink_Id | Ingredient_Id | Proportion |
+----------+---------------+------------+
| 1 | 1 | 70 |
| 1 | 2 | 10 |
| 1 | 3 | 20 |
| 2 | 1 | 90 |
| 2 | 4 | 10 |
| 3 | 1 | 80 |
| 3 | 4 | 10 |
| 3 | 5 | 10 |
+----------+---------------+------------+
I'm adding this Proportion column to show you how to add data that is dependant on the pair of drink-ingredient. Now, if you're worried about the size of the tables it'll be quite small as the only tables that will have the more complex data types (varchars) will be the ingredients and drinks tables, which will have the minimum amount of records possible: one per each drink and one per each ingredient.
If you still have doubts keep looking at the example, you'll get it :)
I would do a table for ingredients with a description and an id, and store the ids in the drink table cause it's the elegant way to do it. For 100 drinks, you won't see a difference for the performance.

Resources