Column in SQL table with reference to multiple tables - sql

I have a table Page [Id, Name]. And table Element[Id, PageId, ViewId, ViewType, Order], where ViewType is name one of the tables: Portfolio, Fund, Position. And ViewId is id of element in relevant table: PortfolioView, FundView, PositionView.
View tables looks like: [Id, PortfolioId, ShowName, ShowYTD, ShowMTD and other]. When I create an item of Element it means that created item of one of the "view" tables.
So for me it looks like a antipattern.
In short, I wish create a model of Page, which contains a ordered Elements which represent a one of the Views (portfolio, fund or position). Which way is better to do it in sql?

The way I've seen this done is to update your Element table with a column for each of Portfolio, Fund, and Position. The columns need to be nullable, but they'll be legal foreign keys, so SQL will enforce foreign key correctness for you.
If you want to be as technically correct as possible, you could also do the following:
Page[Id, Name]
Element[Id, PageId, ViewId, ViewType, Order]
Element_Portfolio[ElementId, PortfolioId]
Element_Fund[ElementId, FundId]
Element_Position[ElementId, PositionId]
Portfolio[...]
Fund[...]
Position[...]
This avoid having nullable columns, but requires you to have more tables and therefore more joins when you do a query.

Related

fact table should have measures from 'weak entity' or only parent entity's fields should be entered

i am new to dimension modeling and OLAP.
I am trying to create a dimension model for a shop.
"order" table is having columns:
'order_id(auto generated), total_order_cost, date, product_Set_Id'.
"Product_set" table (contains products ordered in each order i.e. multiple rows for each order, tables logically linked by 'product_set_id' column) has columns:
'product_set_id, product_name, quantity,Cost_per_quantity'.
In the ER model "product_set" table is kind of weak entity dependent on "order" table.
My doubt is in the fact table
case 1: i should add only 'order_id(fk)' and 'total_order_cost(as measure)'
==>in this case measures from "product_set" won't be there in fact table.
or case 2:i should add 'order_id(fk)','product_set_id(fk)' and 'cost_per_quantity(measure), quantity(measure), total_order_cost(measure)'
==>in this case there will be multiple rows for same 'order_id' and 'total_order_cost'
There are other some tables like "customer" etc but i have doubt in above mentioned.
Thanks in advance!
one suggestion always made is to create a surrogate key on the tables. My fact sales is such that it has the surrogate key which allows me to have the orderline data there and each orderline identified by a surrogate key (which I don't really use - but its not an issue) . That way you can follow case 2.
Does that answer the question?

Updating id references into additional table

I'm having a little trouble (possibly codeblind currently) when it comes to migrating some data.
I have 2 tables, one is an appliance table, the other lists manufacturers. The original database stores all the data in a single table, which I'm splitting into multiple tables. I've managed to extract the manufacturers fine, as with the rest of the appliance details to the relevant tables. What I'm failing to do is link the id of the manufacturer to the appliance.
So what I want is for the id in the appliance table to be the corresponding id relative to the manufacturer name in the other table, but done in a single query from the original source material.
My original insert code as follows:
insert into c_appliance (app_serial, property_id, app_location,
app_installdate, app_warrantyexp, app_nextservice)
select [Serial No#], [Customer Number], location,
installed, [Expiry Date], [Service Due]
from dbo.[Customer Table]
This doesn't add the manufacturer into the appliance table - which I'm aware of. The manufacturer column currently remains as null while i attempt to figure out what I'm missing.
Any help would be greatly appreciated!
First of all create a unique key column in original table (temporarily) if not there.
Then insert in first table, as in the above query you are inserting in c_appliance. Also add the temporary unique key column.
Similarly insert into Manufacturer table in the same way, with temporary unique key column.
Now update you can set primary key and foreign keys on the basis of this unique key column.

How to use SQL Server views with distinct clause to Link to a detail table?

I may be total standard here, but I have a table with duplicate values across the records i.e. People and HairColour. What I need to do is create another table which contains all the distinct HairColour values in the Group of Person records.
i.e.
Name HairColour
--------------------
Sam Ginger
Julie Brown
Peter Brown
Caroline Blond
Andrew Blond
My Person feature view needs to list out the distinct HairColours:
HairColour Ginger
HairColour Brown
HairColour Blond
Against each of these Person feature rows I record the Recommended Products.
It is a bit weird from a Relational perspective, but there are reasons. I could build up the Person Feature"View as I add Person records using say an INSTEAD OF INSERT trigger on the View. But it gets messy. An alternative is just to have Person Feature as a View based on a SELECT DISTINCT of the Person table and then link Recommended Products to this. But I have no Primary Key on the Person Feature View since it is a SELECT DISTINCT View. I will not be updating this View. Also one would need to think about how to deal with the Person Recommendation records when a Person Feature record disappeared since since it is not based on a physical table.
Any thoughts on this please?
Edit
I have a table of People with duplicate values for HairColour across a number of records, e.g., more than one person has blond hair. I need to create a table or view that represents a distinct list of "HairColour" records as above. Against each of these "HairColour" records I need link another table called Product Recommendation. The main issue to start with is creating this distinct list of records. Should it be a table or could it be a View based on a SELECT DISTINCT query?
So Person >- HairColour (distinct Table or Distinct View) -< Product Recommendation.
If HairColour needs to be a table then I need to make sure it has the correct records in it every time a Person record is added. Obviously using a View would do this automatically, but I am unsure whether you can can hang another table off a View.
If I understand correctly, you need a table with a primary key that lists the distinct hair colors that are found in a different table.
CREATE TABLE Haircolour(
ID INT IDENTITY(1,1) NOT NULL,
Colour VARCHAR(50) NULL
CONSTRAINT [PK_Haircolour] PRIMARY KEY CLUSTERED (ID ASC))
Then insert your records. If this is querying a table called "Person" it will look like this:
INSERT INTO Haircolour (Colour) SELECT DISTINCT HairColour FROM Person
Does this do what you are looking for?
UPDATE:
Your most recent Edit shows that you are looking for a many-to-many relationship between the Person and ProductRecommendation tables, with the HairColour table functioning as a cross reference table.
As ErikE points out, this is a good opportunity to normalize your data.
Create the HairColour table as described above.
Populate it from whatever source you like, for example the insert statement above.
Modify both the Person and the ProductRecommendation tables to include a HairColourID field, which is an integer foreign key that points to the PK field of the HairColour table.
Update Person.HairColourID to point to the color mentioned in the Person.HairColour column.
Drop the Person.HairColour column.
This involves giving up the ability to put free form new color names into the Person table. Any new colors must now be added to the HairColour table; those are the only colors that are available.
The foreign key constraint enforces the list of available colors. This is a good thing. Referential integrity keeps your data clean and prevents a lot of unexpected errors.
You can now confidently build your ProductRecommendation table on a data structure that will carry some weight.
Are you simply looking for a View of distinct hair colors?
CREATE VIEW YourViewName AS
SELECT DISTINCT HairColour
FROM YourTableName
You can query this view like a table:
SELECT 'HairColour: ' + HairColour
FROM YourViewName
If you are trying to create a new (temp) table, the syntax would look like:
SELECT Name, HairColour
INTO #Temp
FROM YourTableName
GROUP BY Name, HairColour
Here the GROUP BY is doing the same work that a DISTINCT keyword would do in the select list. This will create a temp table with unique combinations of "Name" and "HairColour".
You need to clear up a few things in your post (or in your mind) first:
1) What are the objectives? Forget about tables and views and whatever. Phrase your objectives as an ordinary person would. For example, from what I could gather from your post:
"My objective is to have a list of recommended products based on each person's hair colour."
2) Once you have that, check what data you have. I assume you have a "Persons" table, with the columns "Name" and "HairColour". You check your data and ask yourself: "Do I need any more data to reach my objective?" Based on your post I say yes: you also need a "matching" between hair colours and product ids. This must be provided, or programmed by you. There is no automatic method of saying for example "brown means products X,Y,Z.
3) After you have all the needed data, you can ask: Can I perform a query that will return a close approximation of my objective?
See for example this fiddle:
http://sqlfiddle.com/#!2/fda0d6/1
I have also defined your "Select distinct" view, but I fail to see where it will be used. Your objectives (as defined in your post) do not make this clear. If you provide a thorough list in Recommended_Products_HairColour you do not need a distinct view. The JOIN operation takes care of your "missing colors" (namely "Green" in my example)
4) When you have the query, you can follow up with: Do I need it in a different format? Is this a job for the query or the application? etc. But that's a different question I think.

Linking or Mapping two tables together

Consider my data as inventory list separated by categories.
When I started I had one table that should have been split into two tables, else in the oldTable the columns in a given row would have been un-related. I have created two new tables in my database, one for categories and the other for data/items. Now I am trying to use the oldTable existing data to fill the newTable data/items table so I can learn SQL and not have to manually do it. The categories table I filled in manually because I could not see how to do it otherwise.
The old table has:
tableName (
id,
categoryA,
categoryB,
categoryC,
categoryD,
categoryE,
categoryF,
isPriorityA,
isPriorityB,
isPriorityC,
isPriorityD,
isPriorityE,
isPriorityE
)
The new tables have:
Categories (
cat_id,
name
)
dataItem (
item_id,
cat_id,
name,
priority,
description,
URL
)
How do I force the new dataItem table to require the cat_id match one of the values in the Categories.cat_id table column? Perhaps to give an error if a value is added outside of the range? I believe this may be mapping or linking tables, to thereby make them relationship tables.
How do I copy the tableName data to the dataItem table one column at a time in alphabetical order bringing the name,priority with it and allowing it to auto-increment the item_id value?
Sounds like you want to use a foreign key to limit dataItem.cat_id to values in Categories.cat_Id. Something like this:
ALTER TABLE dataItem ADD FOREIGN KEY (cat_id) REFERENCES Categories(cat_id);
Exact syntax may depend on which database you are using. For more info on foreign keys see: http://www.w3schools.com/sql/sql_foreignkey.asp

Join performance

My situation is:
Table member
id
firstname
lastname
company
address data ( 5 fields )
contact data ( 2 fields )
etc
Table member_profile
member_id
html ( something like <h2>firstname lastname</h2><h3>Company</h3><span>date_registration</span> )
date_activity
chat_status
Table news
id
member_id (fk to member_id in member_profile)
title
...
The idea is that the full profile of the member, when viewed is fetched from the member database, in for instance a news overview, the smaller table which holds the basis display info for a member is joined.
However, i have found the need for more often use for the member info that is not stored in the member_profile table, e.g. firstname, lastname and gender, are nescesary when someone has posted a news item (firstname has posted news titled title.
What would be better to do? Move the fields from the member_profile table to the member table, or move the member fields to the member_profile table and perhaps remove them from the member table? Keep in mind that the member_profile table is joined a lot, and also updated on each login, status update etc.
You have two tables named member so i have the feeling your question isn't formed correctly.
What is the relationship between these tables? It looks like you have 3 tables, all one-to-one. So all you need to do is change (fk to member_id in member_profile) to (fk to id in member).
Now you can join in data from either of the 2 extra tables as you wish, without always having to go through member_profile.
[Edit] Also I assume that member_profile.member_id is a fk to member.id. If not, I believe it should :)
Combine them into one table so you're normalizing the name data then create 2 views which replicate the original two tables would be the easy option
Separating the tables between mostly-static fields and frequently-updated fields will improve write performance. So I would stay with what you're doing. If you cache the information from both tables together in a member object, read performance (and thus joining) is less of an issue.