Handling many-to-many relationship in a sql query - sql

So as you know in data modeling, the many-to-many relationships are handled by creating a bridge table. This will enable us to have foreign key constraints.
My question relating to query data from tables that have many-to-many relationships.
I will give an example. Let's say we have the following tables
Table 1
Column 1
Column 2
Column 3
Table 2
Column 1
Column 4
Column 5
Table 3 (bridge table)
Column 1
Ok, so when I tried to query data from table 1 and left joining with table 2 I got the same results as query data from table left joining with table 3 and left joining with table 2. And that makes me wonder if the bridge table is a necessary step to include in a SQL query!
Thank you in advance :)

Your bridge table has just one column, which suggests that you are confusing one-to-many relationships (or many one-to-one), and many-to-many relationships.
In a one-to-many relationship, the child table refers directly to the parent table, and there is no need for a bridge table:
create table orders (
order_id int primary key,
order_date date,
...
);
create table order_items (
order_item_id int primary key,
order_id int references orders(order_id),
...
)
In a many-to-many relationship, the bridge table has (at least) two columns, one for each of the referential table that come into play in the relation:
create table authors (
author_id int primary key,
name varchar(50),
...
);
create table books (
book_id int primary key,
title varchar(50),
...
);
create table book_authors (
author_id int references authors(author_id),
book_id int references books(book_id),
primary key (author_id, book_id)
)

Let's make your example less abstract. There are posts with dislikes and likes. Table 1 = likes, Table 2 = dislikes.
Table likes (post_id, who, why)
Table dislikes (post_id, who, why)
The bridge table is then
Table posts (post_id, content)
This is an example where two child tables are related by a parent table. You don't create the bridge table in order to get an m:n relation between the two child tables, but because the child tables make no sense without their parent table. The child tables are m:n related, but we don't usually call this an m:n relation, because the tables are only losely related (a like belongs to a post and a dislike belongs to a post, but the like doesn't really belong to the dislike).
When talking about m:n relations, we are usally not talking about parent/child relationship.
An example: An order can contain many products and a product can be in many orders.
Table orders (order_id, date)
Table products (product_id, name, price)
The bridge table is the position in the order:
Table order_detail (order_id, product_id, amount)
There is no parent/child relation between orders and products, but the two are related, because products get ordered. This is what we typically call an m:n relation. The bridge table establishes the relation between order and product.

Related

query with SQL m:n relationships

I have a quick question with respect to many to many relationships in sql.
So theoretically i understand that if 2 entities in an ER model have a M:N relationship between them, we have to split that into 2 1:N relationships with the inclusion of an intersection/lookup table which has a composite primary key from both the parent tables. But, my question here is , in addition to the composite primary key, can there be any other extra column added to the composite table which are not in any of the 2 parent tables ? (apart from intersectionTableId, table1ID, table2ID) a 4rth column which is entirely new and not in any of the 2 parent tables ? Please let me know.
In a word - yes. It's a common practice to denote properties of the relationship between the two entities.
E.g., consider you have a database storing the details of people and the sports teams they like:
CREATE TABLE person (
id INT PRIMARY KEY,
first_name VARCHAR(10),
last_name VARCHAR(10)
);
CREATE TABLE team (
id INT PRIMARY KEY,
name VARCHAR(10)
);
A person may like more than one team, which is your classic M:N relationship table. But, you could also add some details to this entity, such as when did a person start liking a team:
CREATE TABLE fandom (
person_id INT NOT NULL REFERENCES person(id),
team_id INT NOT NULL REFERENCES team(id),
fandom_started DATE,
PRIMARY KEY (person_id, team_id)
);
Yes, you can do that by modeling the "relationship" table yourself explicitly (just like your other entities).
Here are some posts about exactly that question.
Create code first, many to many, with additional fields in association table
Entity Framework CodeFirst many to many relationship with additional information

Both sides of a many to many relationship also relate to the same 3rd party

In a relational database. Two tables can be related in a many to many fashion with a mapping table that has foreign keys to the other two tables primary keys, while both still being related to another table.
For example.
Table A
AId -PK
CId -FK
Table B
BId -PK
CId -FK
Mapping Table m
AId -FK
BId -FK
(composite PK of the above)
Table C
CId -PK
How would I modify this so both the tables in the many to many relationship setup in such a way that a row from Table A and a row from Table B can only be related to each other through mapping table m if the row in A and B are also related to the same row in Table C?
1. Make TableA.CId and TableB.CId both FKs to Table C.ID.
2. Add a unique index in TableA on columns AId and CId.
3. Add a unique index in TableB on columns BId and CId.
4. Add a CId column to TableM.
5. Then Add two FKs in Table M,
a. One using columns (AId, CId) pointing to Unique composite Index in Table A, and
b. the other using columns (BId, CId) pointing to Unique composite Index in Table B.

A table with all attributes making the primary key

I have two tables: Student and Shop and I would like to record information about which student visited which shop and if the number of visits is above n, they should received a discount:
This is how I did it:
All of attributes (studentID, shopID, time, date) in table StudentShop makes the primary key for this table. I just wanted to know if this design is good?
As relation between entieties Student - Shop is many to many relationship,
it is always implemented using associative table (consists of primary keys from both relations), so StudentShop table - is good choice for implementation of such relation.

Sql modifying relationships

how do you change the relationship between two tables to a many to many to many relationship in sql. Im using oracle for the DB.
thanks
Relationships among tables are almost always, ONE-TO-MANY, or ONE-TO-ONE. There is no MANY-TWO-MANY relationship between two tables. If you want a MANY-TO-MANY you will need to create intermediate relation to hold the relationship.
For example, if you want a MANY-TO-MANY relationship between table A and B you will need to create an intermediate table C:
create table a (a_id number primary key);
create table b (b_id number primary key);
-- c will hold many-to-many relationship between a and b
create table c (
a_id number not null references a(a_id),
b_id number not null references b(b_id),
primary key(a_id, b_id)
);

Designing 1:1 and 1:m relationships in SQL Server

In SQL Server 2008, how does one design a 1:1 and 1:m relationship?
Any relationship requires that the "parent" table (the one side) have a Primary (or unique) Key (PK), that uniquely identifies each row, and the "child" table (the other side) have a Foreign Key column or columns, that must be populated with values that are the same as some existing value[s] of the Primary Key in the parent table. If you want a one to many (1-M) relationship then the Foreign Key should be an ordinary attribute (column or columns) in the child table that can repeat (there can be many rows with the same value)
If you want a one to one (1-1) relationship then the Foreign key should itself be a Primary Key or unique index in the child table that guarantees that there may be at most one row in the child table with that value.
A 1-1 relationship effectively partitions the attributes (columns) in a table into two tables. This is called vertical segmentation. This is often done for sub-classing the table entities, or, for another reason, if the usage patterns on the columns in the table indicate that a few of the columns need to be accessed significantly more often than the rest of the columns. (Say one or two columns will be accessed 1000s of times per second and the other 40 columns will be accessed only once a month). Partitioning the table in this way in effect will optimize the storage pattern for those two different queries.
Sub-Classing. The above actually creates a 1 to zero or one relationship, which is used for what is called a sub-class or subtype relationship. This occurs when you have two different entities that share a great number of attributes, but one of the entities has additional attributes that the other does not need. A good example might be Employees, and SalariedEmployees. The Employee table would have all the attributes that all employees share, and the SalariedEmployee table would exist in a (1-0/1) relationship with Employees, with the additional attributes (Salary, AnnualVacation, etc.) that only Salaried employees need.
If you really want a 1-1 relationship, then you have to add another mechanism to guarantee that the child table will always have one record for each record/row in the parent table. Generally the only way to do this is by enforcing this in the code used to insert data (either in a trigger, stored procedure or code outside the database). This is because if you added referential integrity constraints on two tables that require that rows always be in both, it would not be possible to add a row to either one without violating one of the constraints, and you can't add a row to both tables at the same time.
One-to-One Relationship
Create Table ParentTable
(
PrimaryKeyCol ... not null Primary Key
, ...
)
Create Table ChildTable
(
, ForeignKeyCol ... [not] null [Primary Key, Unique]
, ...
, Constraint FK_ChildTable_ParentTable
Foreign Key ( ForeignKeyCol )
References ParentTable( PrimaryKeyCol )
)
In this case, I can never have more than one row in the ChildTable for a given ParentTable primary key value. Note that even in a One-to-One relationship, one of the tables is the "parent" table. What differentiates a One-to-One relationship from a One-to-Many relationship purely in terms of implementation is whether the ChildTable's foreign key value has a Unique or Primary Key constraint.
One-to-Many Relationship
Create Table ParentTable
(
PrimaryKeyCol ... not null Primary Key
, ...
)
Create Table ChildTable
(
, ForeignKeyCol ... [not] null
, ...
, Constraint FK_ChildTable_ParentTable
Foreign Key ( PrimaryKeyCol )
References ParentTable( PrimaryKeyCol )
)
In this scenario, I can have multiple rows in the ChildTable for a given ParentTable primary key value.
A 1:1 relationship exists where table A and table B only exist once in regards to each other.
Example: A student has 1 master student record. The student would be table A and the record in table B. Table B would contain a foreign key to the student record in table A (and possibly vice-versa)
A 1:m relationship exists where table A can be referenced or linked to by many entries in table B.
Example: A student can take several books out from the library. The student again would be table A and the book could be the entry in table B. The entry in table B would contain a foreign key to who checked the book out, and many books could reference the same student.