SQL Referencing a particular table chosen from a row value in another table - sql

I've got a database called SimpleCredentials in which there is a table called dbo.Properties which has (PK) UserID and then some other attributes like Name, Date of Birth etc. There is another Primary Key attribute called ExtendedCredentials which is a string dbo.UserID. So, for example the user with UserID = S-1-5-21-2177 will have the string dbo.S15212177 in their ExtendedCredentials column.
I've got another database called ExtendedCredentials. For every User there is a unique table in that database. Using the previous example, there will be a table called dbo.S15212177.
So, if I have 100 users there will be 100 rows in the dbo.Properties table in the SimpleCredentials database, and there will be 100 unique tables incorporating their UserID in the ExtendedCredentials database.
I want to create an entity relationship diagram, and eventually a MS SQL schema, but how do I represent the multiplicity of dbo.UserIDs and their relationship to their dbo.UserID string attribute in dbo.Properties?
Am I getting something fundamentally wrong here?
You may ask why I don't have a single database called ExtendedProperties with a single table in which each row is the UserID PK and the various extended properties are contained in columns. The simple answer is that some properties are themselves tables. Not every user has the same attributes in those tables. And I can't know ahead of time (a priori) what the full set of user extended property attributes is. So each user gets a table of their own.
Is there a better way to do this?

Related

Sql server, insert data into two tables, populate one before the other

My first post here as I am starting in a new job where my old sql skills already are on the test - I am not advanced user from before either.
I believe there might be some answers here already that might be answering my question, but I am still a bit unfamiliar - both with the forum and more advanced sql syntaxes. Some answers are pretty old as well.
And - please excuse me for any grammatical errors.
Anyways, if anyone might be able to help.
I will be receive huge lists (.csv or similar) with data input.
The datalists will contain fields for type customerdata (name, address etc) and fields for type real estate/property data (street address, buildingIDs etc).
The customerdata and propertydata needs to be put into two separate tables.
My problem is like this:
- The two tables are depended on eachother as in the propertydata table needs to be populated with data first, which will generate a unique GUID - which again will be used when populating the customerdata table - connecting the customer to the correct property/real estate.
The first thing that came to mind is to populate all data into a temporary table.
But I am not quite sure how to loop through each row so I ensure that propertytable is populated first, then the customertable using the GUID.
Get data that involves propertydata and populate the property table
Get the unique GUID generated in property table
Get data that involves customerdata and populate the customer table - with correct GUID
Loop through rest of the set until there are no more rows with data.
I have seen some things like transactions, cursors, output etc that seems to be within my scope, but not sure which would be best way to solve my challenge? Am I near something when thinking like that?
EDIT:
These are example fields that will come as one row in .xlsx/.csv format.
Number of rows in such list will vary from time to time.
Property ID
Property address
Property building ID (only one)
Property established date
...Misc other property related fields
Customer ID
Customer Name
Customer Address
Postal code
...Misc other customer related fields
Fields 1 through 5 will need to populate a property table first. When each row in property table is populated it will generate unique GUID.
Then fields 6 through 10 will be used to populate a customer table, but also need to be populated with the corresponding unique GUID created above in the property table.
Property table:
Property ID
Property address
Property building ID (only one)
Property established date
...Misc other property related fields
UNIQUE PROPERTY GUID (created when populating each new row in table)
Customer table:
UNIQUE PROPERTY GUID
Customer ID
Customer Name
Customer Address
Postal code
...Misc other customer related fields
I suggest you use a staging table.
Load all data into a staging / temporary table and assign GUID numbers to each row.
Copy property details from staging table to property table taking GUID from the staging table
Copy customer details from staging table to customer table taking GUID from the staging table.
Delete data in staging table.
A quick example:
INSERT INTO PropertyDetails( GUID, PropertyID, PropertyAddress, ... )
SELECT GUID, PropertyID, PropertyAddress, ...
FROM StagingTable
INSERT INTO CustomertDetails( GUID, CustomerID, CustomerName, ... )
SELECT GUID, PropertyID, PropertyAddress, ...
FROM StagingTable

How to structure database, multiple foreign keys?

I feel like this may be a bit of a unique problem, but hopefully someone out there has come across a similar situation.
My application uses this database table:
DT table
The issue is with Field1 - 9.
Depending on how the user decides to set up their instance of the app there can be any number of fields used (from 0 - 9). The information for these are held in this Table:
Field Table
So for this example there are only to be two fields. And when a record is created for the DT table, field 1 and 2 will have data entered and all other field columns will be NULL. Obviously this isn't good practice, as for one, if a field name was changed in the future, all previous data wouldn't make sense.
I've been trying to think of a way to structure it differently. all I can think of is somehow when a DT record is created it will hold foreign keys to the fields that were used, but it seems that it's not possible to have multiple foreign keys in one column.
Any help or suggestions would be greatly appreciated.
One way to normalize this would be to factor out the repeating fields to a separate table, where you would have one entry per field with DT_id as a foreign key to the DT table.
DT Table:
ID
Start
End
...
DT_field table:
ID
DT_id (foreign key)
Value

How to deal with one single cell containg multiple values?

I'm having an exercise requiring to create two table for a travel business:
Activity
Booking
it turns out that the column activities in the Booking table references from the Activities table. However it contains multiple value. How do I sort it out? If I insert multiple rows there will possibly duplication in the Booking's primary key.
As Gordon mentioned you should refactor your tables for better normalization. If I interpret your intent correctly this is more like what your schema should look like. Booking should only contain an ID for adventure and an ID for Customer. You will add a row to [AdventureActivity] for each activity booked on a [Booking]. With this design you can JOIN tables and get all the data you require without having to try to parse out multiple values in a column.

decompose source data into new, many-to-many schema

I am using MS Access 2010 to do some transformations of data. Specifically, I need to create the data structure for a many-to-many relationship between concept (summarized by rxnconso.rxcui) and word (summarized by drugwords.id. Note that each value of drugwords.id needs to correspond with a unique value of name from the words table in the images below.). To accomplish this, I need to create two tables, drugwords and drugwordsConsoJunction, and also decompose the contents of an existing table words into the drugwords and drugwordsConsoJunction tables. The structure of the destination tables is:
drugwords table: (this table needs to be created)
id (autonumber pk needs to be created from distinct values of words.name)
name
drugwordsConsoJunction: (this table needs to be created)
word_id (fk to drugwords.id)
rxcui (fk to rxnconso.rxcui)
rxnconso (this table already exists):
rxcui
...other fields
The source table for this transformation is called words and has two columns; a value for rxcui, and a value for name. As you can see from the images below, there can be many name values for a given rxcui value. And the second image below shows that there can be many rxcui values for a given name value.
How do I write the SQL to transform words into drugwords and drugwordsConsoJunction, as per the above specifications?
I have uploaded a copy of the database to a file sharing site. You can download it at this link.
If the proposed [drugwords] table is already going to have unique values in its [name] column then you don't need an AutoNumber ID column, you can just use the [name] field as a Primary Key. In that case, the table that maps "words" to the corresponding [rxcui] values could be created by simply doing
SELECT DISTINCT rxcui, [name] INTO drugwordsConsoJunction FROM words
Then you can use the "words" themselves instead of introducing another layer of mapping from (distinct) "words" to (distinct) "IDs".

How to display multiple values in a MySQL database?

I was wondering how can you display multiple values in a database for example, lets say you have a user who will fill out a form that asks them to type in what types of foods they like for example cookies, candy, apples, bread and so on.
How can I store it in the MySQL database under the same field called food?
How will the field food structure look like?
You may want to read the excellent Wikipedia article on database normalization.
You don't want to store multiple values in a single field. You want to do something like this:
form_responses
id
[whatever other fields your form has]
foods_liked
form_response_id
food_name
Where form_responses is the table containing things that are singular (like a person's name or address, or something where there aren't multiple values). foods_liked.form_response_id is a reference to the form_responses table, so the foods liked by the person who has response number six will have a value of six for the form_response_id field in foods_liked. You'll have one row in that table for each food liked by the person.
Edit: Others have suggested a three-table structure, which is certainly better if you are limiting your users to selecting foods from a predefined list. The three-table structure may be better in the case that you are allowing them the ability to enter their own foods, though if you go that route you'll want to be careful to normalize your input (trim whitespace, fix capitalization, etc.) so you don't end up with duplicate entries in that table.
normally, we do NOT work out like this. try to use a relation table.
Table 1: tbl_food
ID primary key, auto increment
FNAME varchar
Table 2: tbl_user
ID primary key, auto increment
USER varchar
Table 3: tbl_userfood
RID auto increment
USERID int
FOODID int
Use similar format to store your data, instead a chunk of data fitted into a field.
Querying in these tables are easier than parsing the chunk of data too.
Use normalization.
More specifically, create a table called users. Create another called foods. Then link the two tables together with a many-to-many table called users_to_foods referencing each others foreign keys.
One way to do it would be to serialize the food data in your programming language, and then store it in the food field. This would then allow you to query the database, get the serialized food data, and convert it back into a native data structure (probably an array in this case) in your programming language.
The problem with this approach is that you will be storing a lot of the same data over and over, e.g. if a lot of people like cookies, the string "cookies" will be stored over and over. Another problem is searching for everyone who likes one particular food. To do that, you would have to select the food data for each record, unserialize it, and see if the selected food is contained within. This is a very inefficient.
Instead you'll want to create 3 tables: a users table, a foods table, and a join table. The users and foods tables will contain one record for each user and food respectively. The join table will have two fields: user_id and food_id. For every food a user chooses as a favorite, it adds a record to the join table of the user's ID and the food ID.
As an example, to pull all the users who like a particular food with id FOOD_ID, your query would be:
SELECT users.id, users.name
FROM users, join_table
WHERE join_table.food_id = FOOD_ID
AND join_table.user_id = users.id;