merge two crossreference tables? - database

I have three tables with many-to-many relationships:
profile, role and type
Then, I have two cross-reference tables:
profile_role:
role_id : int
profile_id : int
profile_type:
profile_id : int
type_id : int
The common external id in both tables is profile_id.
My idea is that I create a table that contains the three external ids:
profile_role_type:
role_id : int
profile_id : int
type_id : int
My question : is the two designs are equivalent (no data loss or redundancy)?

profile_role_type would only be a valid replacement if there is exactly one row in profile_role with the same profile_id for every row in profile_type.
That's the long and the short of it.

Related

Mapping ID values using SQL

Assume you have 2 DB with matching table structures in both.
For example,
D1.T1(ID, VAL) = D2.T1(ID,VAL)
D1.T2(ID, NAME,FID) = D2.T2(ID, NAME,FID)
Where D1.T2.FID = D1.T1.ID
Now I want to copy rows from D1 to D2. But ID values changes during the insert into D2 (not because I can't force insert the same ID by using IDENTITY_INSERT, its because the same ID exist in D2.T1 for some other values).
Now I need to update the D2.T2 with the new identity values. How can this be done, without altering tables (to persist the old_id value in D2.T1 and doing an update later on on D2.T2 by comparing the old id value)?
To give a hint of the tables structure see below.
D1.T1
ID, VAL
4934, A
4936, B
5011, C
D1.T2
ID, NAME, FKID
2478, I, 4934
2479, II, 4936
2481, III, 5011
D2.T1
ID, VAL
7813, A
7817, B
7819, C
D2.T2
ID, NAME, FKID
3416, I, 7813
3417, II, 7817
3419, III, 7819
So, for example, we now come across a
D1.T1 of 7813, D
and then discover that 7813 already exists in D2.T1??
"But ID values change during the insert into D2"
What does it change to? say 9876 ?? So now D2.T1 would be 9876, D
Well, lets go on and try to copy
D1.T2 of 2482, IIII, 7813
BUT WAIT >> How do we know if this 7813 refers to 7813, A or 7813, D
We don't know, We cannot determine if we need to keep 7813 or change to 9876.
Ergo, we need more information that resides in the table, e.g. another column.

Use many to many relationship or multiple columns?

I have a product, which can belong to one (or more) of 5 possible categories.
The number/name/structure of categories will not change
Should I be using a many to many relationship and insert 5 records in the category table, add a join table and add foreign keys etc? Or just add 5 fields to the product table? I feel the latter seems more efficient, but goes against the principles of normalization.
i.e.
Product:
- id
- name
- is_cat_a : bool
- is_cat_b : bool
- is_cat_c : bool
- is_cat_d : bool
- is_cat_e : bool
OR
Product
- id
- name
Category
- id
- name
ProductCategories
- product_id
- category_id
As you suggested:
A product, which can belong to one (or more) of 5 possible categories only.
Then, in my opinion, create two tables:
**1. Category**
Id int,
Name varchar,
IsActive bool and other regular columns
**2. Product**
- id int,
- name varchar,
- cat_a : int,
- cat_b : int,
- cat_c : int,
- cat_d : int,
- cat_e : int
Keep all category column's default as zero.

Modeling a non-primary Key relationship

I am trying to model the following relationship with the intent of designing classes for EF code first.
Program table:
ProgramID - PK
ProgramName
ClusterCode
Sample data
ProgramID ProgramName ClusterCode
--------------------------------------
1 Spring A
2 Fall A
3 Winter B
4 Summer B
Cluster table:
ID
ClusterCode
ClusterDetails
Sample data:
ID ClusterCode ClusterDetails
---------------------------------
1 A 10
2 A 20
3 A 30
4 B 20
5 B 40
I need to join the Program table to the Cluster table so I can get the list of cluster details for each program.
The SQL would be
Select
from Programs P
Join Cluster C On P.ClusterCode = C.ClusterCode
Where P.ProgramID = 'xxx'
Note that for the Program table, ClusteCode is not unique.
For Cluster table, neither ClusterCode nor ClusterDetail is unique.
How would I model this so I can take advantage of navigation properties and code-first?
assuming you have mapped above two tables and make an association between them and you are using C#, you can use a simple join :
List<Sting> clustedDets=new ArrayList<String>();
var q =
from p in ClusterTable
join c in Program on p equals c.ClusterTable
select new { p.ClusterDetails };
foreach (var v in q)
{
clustedDets.Add(v.ClusterDetails);
}

How do I select column value based on other column

Hi Right now I am using this code in my MVC project :
AppHistory history = new AppHistory();
history = (from AppHistory app in Market.AppHistories
where app.HistoryID == 11
select app).ToList().FirstOrDefault();
Here I am passing value for app.historyID as 11. In my SQL, this is primary key identity specification. I have userID which I am storing for current users.
So what i should do is instead of passing hardocoded value to app.HistoryID, i need to pass userID parameter here and have to select app.HistoryID based on that userID.
How can i do this?
Update :
My table design is shown below. I was not able to upload snap so I am writing my design below:
ColumnName DataType AllowNulls
HistoryID(Primary key) int No
userUID int Yes
HistoryUserActive int yes
HistoryInactiveFrom int yes
HistoryStart datetime yes
HistoryMonthCost int yes
Update 2:
Can i do like this to check column name based on userID :
int userId = userID
history = (from AppHistory app in termsAccepted.AppHistories
where app.UserID == userId
select app).FirstOrDefault();
Now I need to check whether user has historyID, that is hitory.historyID. For this i need to write if condition like :
if (history.historyID exists)
{
//
}
Here what code i should write to check historyID exists or not?

Help with Grocery List Database design

I want to create a Grocery List Table that will accept both the Category and the Specific Products.
For Example: I add to my grocery list:
Fruit (Category)
Fuji Apple (Product)
Shampoo (Category)
Dove Energize Shampoo (Product)
I have Product Table w/ Manufacturer(reference table), Category Table w/ SubCategoryId.
I want the user to enter either the Category or Product into the Grocery List, but have a way knowing that item entered is either a Category or Product. Please advise.
Any help is much appreciated.
Bogdan solution is a very good solution and if i have your problem i would implement his solution, but if you insist on one column in one table for your grocery list, i guess you have to use substring
like e.g
CREATE TABLE grocery_list (
[groceryItem] varchar(100)
);
Insert into grocery_list ([groceryItem]) values ('(c)Fruit')
Insert into grocery_list ([groceryItem]) values ('(p)Fuji Apple')
Insert into grocery_list ([groceryItem]) values ('(c)Shampoo')
Insert into grocery_list ([groceryItem]) values ('(c)Dove Energize Shampoo')
and to access your table substring the first 2 chars to check the type of your item
Select [item] = case when substring(groceryItem,2,1) = 'c' then
right(groceryItem,len(groceryItem) - 3) + ' (Category)'
when substring(groceryItem,2,1) = 'p' then
right(groceryItem,len(groceryItem) - 3) + ' (Product)'
end
from grocery_list
This will give you the below result
**item**
Fruit (Category)
Fuji Apple (Product)
Shampoo (Category)
Dove Energize Shampoo (Category)
I would create two separate columns, one for categories and one for products:
CREATE TABLE grocery_list (
'category_id' INTEGER NULL FOREIGN KEY categories 'id',
'product_id' INTEGER NULL FOREIGN KEY products 'id',
...
);
Entries will only put a value in one of the two columns, leaving the other as NULL. Then you can query your grocery list like this:
SELECT * FROM grocery_list, categories, products
WHERE categories.id=grocery_list.category_id
AND products.id=grocery_list.product_id;

Resources