Multiple fields in one sheet mapping to single field in another sheet - database

I need help designing the following architecture. Say Table 1 has a list of companies along with their information. Then Table 2 has a list of "primary" companies, followed by multiple fields denoting the companies that they do business with ("secondary" companies). So the first field in Table 2 is the "primary" company, and then there could follow up to 20 columns, each with a single entry of a company that does business with the "primary company". Each of those companies are listed in Table 1. I want to be able to tie the information about those "secondary companies" in with the information about them in Table 1. For example, I want to be able to see how many "secondary" companies in Table 2 are from California. I each company listed once in Table 1 along with headquarters locations; but each company in Table 2 is in a distinct column. I'm just getting confused about how to structure this, because when I try to make a query relationship between Table 1 and Table 2, I end up making a join between "Company" in Table 1 and every column in Table 2. Not good, right?
I have something like this...
Table 1
Company City State
A Los Angeles CA
B San Diego CA
C New York NY
.
.
.
Table 2
Primary Company Secondary1 Secondary2 Secondary3 Secondary4
A B C X Y
B A C Z W
C A B W X
Do I need another table for this? Should I just concatenate these 20+ secondary company fields into one column somehow? Any direction you could give would be very helpful.
Thank you!

I think what you want is this:
Table 1
Company City State
A Los Angeles CA
B San Diego CA
C New York NY
.
.
.
Table 2
Primary Company Secondary
A B
A C
A X
A Y
B A
B C
B Z
B W
...
In this case you will have a relationship between table1, column1 and table2 column 1 and 2. This is acceptable (though technically better if you use numbers instead of letters).

Related

Power BI Table Relationship

I am trying to create two relationships between tables in Power BI. I have a table (Observations) that contains an employee_id and a supervisor_id that I am trying to connect to my Contact table.
I need to look up the employee information in the Contact table by using employee_id in the Observation table and also look up the supervisor information in the Contact table using the supervisor_id in the Observation table.
Contact Table Observation Table
=================== =================
Employee_ID Name Position Observation_ID Employee_ID Supervisor_ID
--------------------------------------- ----------------------------------------------
123 John Doe employee 1 123 321
321 Harvey Sample supervisor 2 456 654
456 Mickey Mouse employee 3 456 654
654 Donald Duck supervisor 4 123 321
One possible way is to create two relationships between the observation and contact table:
Create a relationship between Observation Table(Employee_ID) and Contact Table(Employee_ID). The Cardinality should be many to one, and set this relationship as active.
Create a relationship between Observation Table(Supervisor_ID) and Contact Table(Employee_ID). The Cardinality should be many to one, and set this relationship as inactive.
create an inactive relationship Power BI
You will then need to use the DAX USERELATIONSHIP function when you want to use the inactive relationship in a formula. Here is a detailed explanation of how to use USERELATIONSHIP: https://www.sqlbi.com/articles/userelationship-in-calculated-columns/
Alternatively, you can duplicate the contact table and use one copy for the Employee_ID relationship and the other for the Supervisor_ID relationship. Which option is best will depend on your use case.

How can I associate a single record with one or more PKs

If I had a single record that represented, say, a sellable item:
ItemID | Name
-------------
101 | Chips
102 | Candy bar
103 | Beer
I need to create a relationship between these items and one or more different types of PKs. For instance, a company might have an inventory that included chips; a store might have an inventory that includes chips and a candy bar, and the night shift might carry chips, candy bars, and beer. The is that we have different kinds of IDs: CompanyID, StoreID, ShiftID respectively.
My first though was "Oh just create link tables that link Company to inventory items, Stores to inventory items, and shifts to inventory items" and that way if I needed to look up the inventory collection for any of those entities, I could query them explicitly. However, the UI shows that I should be able to compile a list arbitrarily (e.g. show me all inventory items for company a, all west valley stores and Team BrewHa who is at an east valley store) and then display them grouped by their respective entity:
Company A
---------
- Chips
West Valley 1
-------------
- Chips
- Candy Bar
West Valley 2
-------------
- Chips
BrewHa (East Valley 6)
--------------------
- Chips
- Candy Bar
- Beer
So again, my first though was to base the query on the provided information (what kinds of IDs did they give me) and then just union them together with some extra info for grouping (candidate keys like IDType+ID) so that the result looked kind of like this:
IDType | ID | InventoryItemID
------------------------------
1 |100 | 1
2 |200 | 1
2 |200 | 2
2 |201 | 1
3 |300 | 1
3 |300 | 2
3 |300 | 3
I guess this would work, but it seems incredibly inefficient and contrived to me; I'm not even sure how the parameters of that sproc would work... So my question to everyone is: is this even the right approach? Can anyone explain alternative or better approaches to solve the problem of creating and managing these relationships?
It's hard to ascertain what you want as I don't know the purpose/use of this data. I'm not well-versed in normalization, but perhaps a star schema might work for you. Please keep in mind, I'm using my best guess for the terminology. What I was thinking would look like this:
tbl_Current_Inventory(Fact Table) records current Inventory
InventoryID INT NOT NULL FOREIGN KEY REFERENCES tbl_Inventory(ID),
CompanyID INT NULL FOREIGN KEY REFERENCES tbl_Company(ID),
StoreID INT NULL FOREIGN KEY REFERENCES tbl_Store(ID),
ShiftID INT NULL FOREIGN KEY REFERENCES tbl_Shift(ID),
Shipped_Date DATE --not really sure, just an example,
CONSTRAINT clustered_unique CLUSTERED(InventoryID,CompanyID,StoreID,ShiftID)
tbl_Inventory(Fact Table 2)
ID NOT NULL INT,
ProductID INT NOT NULL FOREIGN KEY REFERENCES tbl_Product(ID),
PRIMARY KEY(ID,ProductID)
tbl_Store(Fact Table 3)
ID INT PRIMARY KEY,
CompanyID INT FOREIGN KEY REFERENCES tbl_Company(ID),
RegionID INT FOREIGN KEY REFERENCES tbl_Region(ID)
tbl_Product(Dimension Table)
ID INT PRIMARY KEY,
Product_Name VARCHAR(25)
tbl_Company(Dimension Table)
ID INT PRIMARY KEY,
Company_Name VARCHAR(25)
tbl_Region(Dimension Table)
ID PRIMARY KEY,
Region_Name VARCHAR(25)
tbl_Shift(Dimension Table)
ID INT PRIMARY KEY,
Shift_Name VARCHAR(25)
Start_Time TIME,
End_Time TIME
So a little explanation. Each dimension table holds only distinct values like tbl_Region. Lists each region's name once and an ID.
Now for tbl_Current_Inventory, that will hold all the columns. I have companyID and StoreID both in their for a reason. Because this table can hold company inventory information(NULL StoreID and NULL shiftID) AND it can hold Store Inventory information.
Then as for querying this, I would create a view that joins each table, then simply query the view. Then of course there's indexes, but I don't think you asked for that. Also notice I only had like one column per dimension table. My guess is that you'll probably have more columns then just the name of something.
Overall, this helps eliminate a lot of duplicate data. And strikes a good balance at performance and not overly complicated data structure. Really though, if you slap a view on it, and query the view, it should perform quite well especially if you add some good indexes.
This may not be a perfect solution or even the one you need, but hopefully it at least gives you some ideas or some direction.
If you need any more explanation or anything else, just let me know.
In a normalized database, you implement a many-to-many relationship by creating a table that defines the relationships between entities just as you thought initially. It might seem contrived, but it gives you the functionality you need. In your case I would create a table for the relationship called something like "Carries" with the primary key of (ProductId, StoreId, ShiftId). Sometimes you can break normalization rules for performance, but it comes with side effects.
I recommend picking up a good book on designing relational databases. Here's a starter on a few topics:
http://en.wikipedia.org/wiki/Entity%E2%80%93relationship_model
http://en.wikipedia.org/wiki/Database_normalization
You need to break it down to inventory belongs to a store and a shift
Inventory does does not belong to a company - a store belongs to a company
If the company holds inventory directly then I would create a store name warehouse
A store belongs to a region
Don't design for the UI - put the data in 3NF
Tables:
Company ID, name
Store ID, name
Region ID, name
Product ID, name
Shift ID, name
CompanyToStore CompanyID, StoreID (composite PK)
RegionToStore RegionID, StoreID (composite PK)
Inventory StoreID, ShiftID, ProductID (composite PK)
The composite PK are not just efficient they prevent duplicates
The join tables should have their own ID as PK
Let the relationships they are managing be the PK
If you want to report by company across all shifts you would have a query like this
select distinct store.Name, Product.Name
from Inventory
join Store
on Inventory.StoreID = Store.ID
join CompanyToStore
on Store.ID = CompanyToStore.StoreID
and CompanyToStore.CompanyID = X
store count in a region
select RegionName, count(*)
from RegionToStore
join Region
on Region.ID = RegionToStore.RegionID
group by RegionName

Programming Logic in Storing Multiple table ids in one table

I have Five Tables as Below
1.tblFruits
2.tblGroceries
3.tblVegetables
4.tblPlants
5.tblDescriptions
All the tables except 5th one tblDescriptions will have ids as one column and as primary key and Items as Second Column.
The column in table 1 to table 4 are similar and as follows
ids item_name
Now i want to store description of the items of the four table in the fifth table as below
Desc_Id Description Ids
Now the problem is since i am storing the ids to identify the description of the items in the other four table i might get similar ids when i put ids of four table together.
Let me know the table design for the above requirement
tblDescription
=====================
id | pk_id | description | type
id : auto_generated id of tblDescription
pk_id : foreign key to linked to the tblFruits,tblGroceries.. table
description : the description
type : value either be fruits, groceries,vegetables,plants .To identify the table.
SQL to extract description would be as below:
Select f.item_name, d.description from tblDescription d
inner join tblFruits f on d.pk_id=f.id and d.type='fruits'
inner join tblGroceries g on d.pk_id=g.id and d.type='groceries'
Use Polymorphic Association. As foreign key of your 5th table with description use two columns object_id and object_model.
Example of table content:
Desc_Id Description Object_ID Object_Model
1 'dsferer' 12 `Fruit`
2 `desc2 12 `Vegetable`
2 `descfdfd2 19 `Vegetable`
Remember to add unique index on both columns for performance reasons.
Here you have some article explaining this in PHP
As your tables are similar, the best practice is to combine all of your tables and even description and define row type using a type column.
id name description type
[Fruits, Groceries, Vegetables, Plants]
It's easier to understand and maintain.
But if your tables are different you have two option:
1- use a super table for your types which produce unique IDs which I suggest.
2- use a type row in your description field and define it as primary key beside ID in that table.

MS Access Relationship help needed

I have 2 MS Access Tables.
Table 1
id
room-name
Table 2
wall
cupboard
ceiling
Now... table1.room-name has the room names and table2 contains object (many) so each room name contains many objects.
My question is ... How do I set the relationships for this please?
Nothing in table 2 tells you what room things are in so you need to add a foreign key of the room to the primary key of table 1. In this case either column of table1 could be its primary key - I would use room- name and drop the id.
So table2 needs altering so that room-name is in it and the draw the connection from table1 to table2.
Something like:
[Room]
RoomId eg 1 2
RoomName eg bedroom kitchen
[RoomItem]
RoomItemId eg 1 eg 2 eg 3
RoomId eg 1 eg 1 eg 2
ItemName eg wardrobe eg bed eg cooker
Where the RoomId links the Room and RoomItem tables.

Database Designing and Normalization issue

I have a huge access mdb file which contains a single table with 20-30 columns and over 50000 rows and
i have some thing like this
columns:
id desc name phone email fax ab bc zxy sd country state zip .....
1 a ab 12 fff 12 w 2 3 2 d sd 233
2 d ab 12 fff 12 s 2 3 1 d sd 233
here I have some column values related to addresses repeating is there a way to normalize the above table so that we can remove duplicates or repeating data.
Thanks in advance.
Here's a quick answer. You just need to move your address fields to a new table (remove dups) and add a FK back to your primary table.
Table 1 (People or whatever)
id desc name phone email fax ab bc zxy sd address_id
1 a ab 12 fff 12 w 2 3 2 1
2 d ab 12 fff 12 s 2 3 1 2
3 d ab 12 fff 12 s 2 3 1 2
4 d ab 12 fff 12 s 2 3 1 1
Table 2 (Address)
address_id country state zip .....
1 d sd 233
2 e ac 123
Jim W has a good start, but to normalize even further, make your redundant address elements into separate tables as well.
Create the tables for which address data is repeated (Country, State, etc.) Once you have your data tables, you'll want to add columns such as StateID, CountryID, etc. to the Address table.
You now have options for fixing the existing data. You can be quick and dirty and use Update statements to set all the newly created ID fields to point to the right data table.
UPDATE Addresses SET StateID=1 WHERE STATE='AL'
You can do this fairly quickly as a batch .sql file, but I'd recommend a more programmatic solution that rolls through the Address table and tries to match the current 'State' to an entry in the new States table. If found, the StateID on the Address table is updated with the id from the corresponding row in States.
You can then delete the old State field from the address table, as it is now normalized nice and neatly into a separate States table.
This process can be repeated for all redundant data elements. However, IMO db normalization can be taken too far. For example, if you have a commonly used query that, after normalization, requires 10 joins to accomplish, you may see a performance reduction. This doesn't appear to be the case here, as I think you're on the right track.
From a comment above:
#Lance i wanted something similar to that but here is the problem i have raw data coming in the form of single table and i need to refine and send it to two tables i can add address in table 2 but i m not undertanding how would you insert the address_id in table 1
You can retrieve the newly created ID from the address table using ##IDENTITY, and update the address_ID with this value.

Resources