Field involving multiple rows from another table - sql

I have created/am creating 3 tables: Slaves, Citizens and Incidents.
How should I go about Incident involving multiple Citizens and Slaves?
Now I'm thinking about making two fields in Incidents containing list of CitizenID's and SlaveID's (SlaveID1, SlaveID2...,SlaveIDn), but it seems plain dumb.

Actually your idea doesn't sound dumb at all. You can design your Incidents table like this:
+------------+-----------+---------+
| IncidentID | CitizenID | SlaveID |
+------------+-----------+---------+
| 1 | A | A | <-- incident #1 involved 2 citizens and 1 slave
| 1 | B | A |
| 2 | A | A | <-- incident #2 involved 2 citizens and 2 slaves
| 2 | B | A |
| 2 | A | B |
| 2 | A | B |
+------------+-----------+---------+
Now when you query for a certain incident ID you can obtain a list of all citizens and slaves involved in the incident. This is a many-to-many relationship in your database schema.

You can make it by making 2 bridge table along with one master table
Master table
_______________
Incidents
Bridge tables
___________
incident_slave(pk of incidents table , slave information field(s) or pk of slave table)
incident_citizen(pk of incidents table , citizen information field(s) or pk of citizen table)

You are looking for a many-to-many relationship.
Basicly you could get away with a table of kind:
CREATE TABLE [dbo].[incidents](
citizen_id*
,slave_id*
)
The * mark means column is a part of primary key. This ensures there is only one relationship between citizen John and slave Patrick.

Related

Select unique combination of values (attributes) based on user_id

I have a table that has user a user_id and a new record for each return reason for that user. As show here:
| user_id | return_reason |
|--------- |-------------- |
| 1 | broken |
| 2 | changed mind |
| 2 | overpriced |
| 3 | changed mind |
| 4 | changed mind |
What I would like to do is generate a foreign key for each combination of values that are applicable in a new table and apply that key to the user_id in a new table. Effectively creating a many to many relationship. The result would look like so:
Dimension Table ->
| reason_id | return_reason |
|----------- |--------------- |
| 1 | broken |
| 2 | changed mind |
| 2 | overpriced |
| 3 | changed mind |
Fact Table ->
| user_id | reason_id |
|--------- |----------- |
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 3 |
My thought process is to iterate through the table with a cursor, but this seems like a standard problem and therefore has a more efficient way of doing this. Is there a specific name for this type of problem? I also thought about pivoting and unpivoting. But that didn't seem too clean either. Any help or reference to articles in how to process this is appreciated.
The problem concerns data normalization and relational integrity. Your concept doesn't really make sense - Dimension table shows two different reasons with same ID and Fact table loses a record. Conventional schema for this many-to-many relationship would be three tables like:
Users table (info about users and UserID is unique)
Reasons table (info about reasons and ReasonID is unique)
UserReasons junction table (associates users with reasons - your
existing table). Assuming user could associate with same reason
multiple times, probably also need ReturnDate and OrderID_FK fields
in UserReasons.
So, need to replace reason description in first table (UserReasons) with a ReasonID. Add a number long integer field ReasonID_FK in that table to hold ReasonID key.
To build Reasons table based on current data, use DISTINCT:
SELECT DISTINCT return_reason INTO Reasons FROM UserReasons
In new table, rename return_reason field to ReasonDescription and add an autonumber field ReasonID.
Now run UPDATE action to populate ReasonID_FK field in UserReasons.
UPDATE UserReasons INNER JOIN UserReasons.return_reason ON Reasons.ReasonDescription SET UserReasons.ReasonID_FK = Reasons.ReasonID
When all looks good, delete return_reason field.

Is it better to use a separate table to store a list of values, or include the value directly in the current table?

I have a jobs table that stores information such as title, department, and salary. I'm wanting the user to be able to create a job using a form that has fields for the aforementioned information, as well as a field for the job category. category would be something like retail, or IT, for example.
I don't have any issues with the actual coding itself, but rather what the best way to design the database store the information in it. So my question is this: should I create a separate table categories that stores each job category, along with an ID, so that the tables would look something like this
categories jobs
+----+---------------+ +----+---------------+-------------+--------+-------------+
| id | category | | id | title | department | salary | category_id |
+----+---------------+ +----+---------------+-------------+--------+-------------+
| 1 | Retail | | 1 | Retail | department1 | 10000 | 2 |
+----+---------------+ +----+---------------+-------------+--------+-------------+
| 2 | IT | | 2 | IT | department2 | 12000 | 1 |
+----+---------------+ +----+---------------+-------------+--------+-------------+
where category_id is a foreign key linking to the categories table,
or should I do something like this, where all the information is stored in a single table:
jobs
+----+---------------+-------------+--------+-------------+
| id | title | department | salary | category |
+----+---------------+-------------+--------+-------------+
| 1 | Retail | department1 | 10000 | IT |
+----+---------------+-------------+--------+-------------+
| 2 | IT | department2 | 12000 | Retail |
+----+---------------+-------------+--------+-------------+
Which is the better option? They both seem to achieve the same result, but what are the pros and cons of doing it either way, and which way would be the more preferred way of doing it?
In general, you want to store "entities" in separate tables. In this case, category is a separate entity from jobs.
Why do you want to do this?
There is only one row per category, so you don't have to worry about duplication -- and errors.
There may be additional information that you want to store, such as the creation date, abbreviation, who created it, and so on.
Properly declared foreign key constraints ensure that only valid categories are stored.
Categories may be shared across different tables, and a separate reference table ensures that the values are consistent.

How can I separate out multiple values from a column via another table?

I have a table named Team. Each record can have more than one member. Rather than jamming members comma separated value, I am hoping to use separate table to meet the requirement. Id is primary key.
----------------------------
| Id | Name | Member
----------------------------
| 1 | TeamA | Jim, Jack
----------------------------
| 2 | TeamB | Micah
I thought of creating a table named User. UserId is the PK and TeamId is FK.
--------------------------
| UserId | Name | TeamId
--------------------------
| 123 | Jim | 1
--------------------------
| 456 | Jack | 1
--------------------------
| 789 | Micah | 2
Then I want parent table Team be able to refer Jim and Jack from its child table but I am not sure how to represent it in one to many relationship... I know below expression is not correct....
------------------------
| id | Name | Member
------------------------
| 1 | TeamA | 123, 456
(Table) Team:
TeamId(PK), Name
(Table) Member:
MemberId(Pk), Name
Case 1 (one to many):
Every Member can be in one team:
Simply add TeamId(FK) to Member Table
Case 2 (many to many):
Every Member can be in as many teams as you want:
Add a linking table:
(Table) TeamMember:
TeamId(FK), MemberId(FK)
That indeed means to normalize data further meaning to split tables your data isnt atomic at each column level. Hence should be normalized to avoid difficulties in data retrievel.
Users Table
User Id(pk) TeamId(fk)
Members Table
TeamId(pk) , MemberId, NAME
Query
Select
u.userid, memberid, m.namefrom
users u join members m
On u.userid=m.memberid and
u.teamid=m.teamid
It looks like you need to create a mapping table to represent the Team, Member relationship, which would make this a many-to-many relationship.
TeamMemberMap - TeamId, MemberId

Foreign key for many to many relationship in sql

I have an SQL table called Listing which is representing houses that have been rented. The table has a primary key id and another field called amenities with the things each house had to offer. The amenities of each house are separated from each other with a comma. For example TV, Internet, Bathroom.
I used the following commands to create a table called Amenity with all the unique different amenities offered and a SERIAL number for each amenity.
CREATE TABLE Amenity AS(
SELECT DISTINCT regexp_split_to_table(amenities,',') FROM Listing
);
ALTER TABLE Amenity
RENAME regexp_split_to_table to amenity_name;
ALTER TABLE Amenity ADD COLUMN amenity_id SERIAL;
ALTER TABLE Amenity ADD PRIMARY KEY(amenity_id);
My problem is that I need to connect these two tables with a foreign key and I don't know how since the relationship between them is a many to many relationship. I have checked other questions regarding foreign keys in many to many relations but could not find anything similar. If there exists something similar please explain the way it is similar to my question.
You must create another table which will hold the one-to-many relationships between a house and its amenities.
So your 3 tables looks look like this:
Table HOUSE
+----------+------------+
| house_id | house_name |
+----------+------------+
| 1 | Uncle Bob |
+----------+------------+
| 2 | Mom Sara |
+----------+------------+
Table AMENITIES
+------------+--------------+
| amenity_id | amenity_name |
+------------+--------------+
| 1 | TV |
+------------+--------------+
| 2 | Internet |
+------------+--------------+
| 3 | Kitchen |
+------------+--------------+
Table HOUSE_AMENITIES
+----------+------------+
| house_id | amenity_id |
+----------+------------+
| 1 | 1 |
+----------+------------+
| 2 | 1 |
+----------+------------+
| 2 | 2 |
+----------+------------+
| 2 | 3 |
+----------+------------+
So the house Uncle Bob has only TV while the house Mom Sara has TV, Internet and a fully equipped kitchen.
Remember - you should never use the same column to store multiple values (separated with comma). In all such cases you have to use another table, converting the multiple comma-separated values into distinct rows inside this detail table and referencing the primary key of the master table.

Database design: two rows or more in a table how to connect them together?

I am making a banking system. When you make a transaction from one account to another i will make to rows/records in my Transaction table. But i need to connect them together, so when i look the transaction up i can see both sides. My question is should i make another table which records this or should i add a column which holds a TransactionHeadID of some kind? Or is there a third and better option?
You can make one table which holds transaction details, senderId and receiverId.
senderId and receieverId will be foreign keys to User table.
One idea would be to add fields "from" and "to" to your Transaction table. Then, if for example you move 100$ from A to 40$ in B and 60$ in C, your table would look like this:
Account | Value | From | To
---------+-------+------+------
A | -40 | NULL | B
A | -60 | NULL | C
B | 40 | A | NULL
C | 60 | A | NULL
However, I think it would be better if you used two tables: a Transaction table containing truly the transaction info indedpendent of from and to accounts, like store,date etc and some TransactionID, and another table called for example TransactionBalanceEvent which would have a TransactionID foreign key, Account number, balance. Then you would have:
Transaction Table
TranID | Date
-------+----------
1 | some_date
TransactionBalanceEvent Table
TranID|Account|Balance
------+-------+-------
1 | A| -100
1 | B| 40
1 | C| 60