I am working on a project where I need to store an unknown length list on names in an sql db. It will be a list of students in a class, which will be different for each class. I also need to be able to search for them (in PHP/SQL) by student name to see all the classes a student attended. I was thinking about storing the class as a row and the students as an array, but I can't figure out an sql to query the arrays in the db. Am I heading the right direction? Maybe creating a new db row for each student for each class? Maybe making the students rows and update an array of classes for each? I will probably using AJAX later to retrieve the info. Thanks!
Why don't you create two tables to store the information about existing Classes and Students and a relation-table Participant that stores the information about which student goes to which class?
Something along the lines of:
CREATE TABLE Classes (
id int NOT NULL,
description varchar(200),
PRIMARY KEY (id)
)
CREATE TABLE Studentes (
id int NOT NULL,
name varchar(200),
PRIMARY KEY (id)
)
CREATE TABLE Participant (
student_id int NOT NULL,
class_id int NOT NULL,
FOREIGN KEY (student_id) REFERENCES Students(id)
FOREIGN KEY (class_id) REFERENCES Classes(id)
)
Then later, you can find out what classes a students visits with a SQL-query like:
SELECT c.description
FROM Students s
LEFT JOIN Participant p ON (s.id = p.student_id)
LEFT JOIN Classes c ON (p.class_id = c.id)
WHERE s.name = 'SilverSlug'
;
What you are looking for is a relations table. It will keep track of class and students. Example
Classes Table : table of all the classes
ID = Primary key
|ID | Name |
| 1 | Math |
Students Table : table of all the students
ID = Primary key
|ID | Name |
| 1 | Sam |
| 2 | Tom |
Relations Table : Used to keep track of an instance of a class
ID = Primary key Class_ID & Student_ID are Secondary keys
|ID | Class_ID | Student_ID | Time |
| 1 | 1 | 1 | 6am |
| 2 | 1 | 2 | 6am |
With these tables you can make simple queries to find out who's in what class, you can also find out what classes a student has.
Related
I am trying to write a query for my sports pick application. I want to display all the information from one table, along with 2 columns from another table. I can write the query that selects all the information from one table, but I am having a difficult time writing the query to add the 2 rows to my answer. Here are the two tables that I am using. This is all in Postgresql by the way.
I want to select everything from this table.
Table "public.weekly_stats"
Column | Type | Modifiers
---------+-----------------------+--------------------
week_no | integer | not null
game_no | integer | not null
home | character varying(40) |
away | character varying(40) |
spread | double precision | not null default 0
winner | character varying(40) |
Indexes:
"weekly_stats_pkey" PRIMARY KEY, btree (week_no, game_no)
Foreign-key constraints:
"weekly_stats_away_fkey" FOREIGN KEY (away) REFERENCES team(name)
"weekly_stats_home_fkey" FOREIGN KEY (home) REFERENCES team(name)
And then I want to display the wins and losses for each team. That uses this table...
Table "public.team"
Column | Type | Modifiers
--------+-----------------------+--------------------
name | character varying(40) | not null
wins | integer | not null default 0
losses | integer | not null default 0
Indexes:
"team_pkey" PRIMARY KEY, btree (name)
Referenced by:
TABLE "weekly_stats" CONSTRAINT "weekly_stats_away_fkey" FOREIGN KEY (away)
I can select all the information from the first table
Select week_no, game_no, home, wins, losses, away, wins, losses, spread, winner from weekly_stats inner join team on name.team = weekly_stats.team;
The SQL you posted is trying to use a field weekly_stats.team which doesn't exist. The teams are in weekly_stats.home and weekly_stats.away and since you have two of them, you need two joins.
And to join the same table twice, you need to give it an alias. Here this is done by adding team1 or team2 after the actual name of the table in the joins:
Select
weekly_stats.week_no,
weekly_stats.game_no,
weekly_stats.home,
team1.wins,
team1.losses,
weekly_stats.away,
team2.wins,
team2.losses,
weekly_stats.spread,
weekly_stats.winner
from weekly_stats
inner join team team1 on team1.name = weekly_stats.home
inner join team team2 on team2.name = weekly_stats.away ;
Inner join will work. If there is any possibility that the table team might be missing a team, you could change it to left join which will give you a NULL for the wins/losses where data is missing in the team table.
See if this is what you want:
SELECT `weekly_stats.*`, SUM(`team.wins`), SUM(`team.losses`)
FROM `weekly_stats`
INNER JOIN `team`
ON `team.name` = `weekly_stats.team`
If I misunderstood you, I'm really sorry.
I want to save multiple rows with single id store in table. What should I do? Please guide me.
For example:
| table1 |
|-----------------|
|id |name |
|001(pk) |Ajit |
| table2 |
|-----------------|
|id(FK) |address |
|001 |Pune |
|001 |Mumbai. |
means TWO TABLES are their in table1 id is primary key & table2 id is foreign key
i.e.: 001 id should multiple address it would be save into table2 but id must be same,
i.e.: address textbox will generate at runtime
Put its(id) default value as "001"(you deserve it) using mysql query and then while inserting a new entry leave that column to add as new.
If you're wanting to link the data in the two tables (i.e. a users table and an addresses table) just use a foreign key.
Your users table:
id | name
================
1 | Martin Bean
Your addresses table:
id | user_id | address
==================================
1 1 Newcastle upon Tyne
This way, the primary key of your addresses table is not dependent on the ID of the users table. And your query to fetch both pieces of data is easy with a join:
SELECT
u.id,
u.name,
a.address
FROM
users u
LEFT JOIN
addresses a ON u.id = a.user_id
I'm new to database design so please bear with me. I'm using PHP and MySQL.
I have a 'movies' table that contains some details about a movie. This includes genres, which have an (if I understand correctly) many to many relationship with movies, implying a single movie can belong to different genres and a single genre can belong to different movies.
From what I gather about database design, storing this kind of relationship in one table is not a good idea as it will either violate First Normal form or Second Normal form rules.
How would I design my tables to avoid this; would I have to create a table for each genre separately or... ?
This leads my to my next question: separate tables need to have foreign keys to identify which information belongs to what row. In theory, if I had a unique key identifying each movie which I would then like to use to identify a director in a separate table, how would I create this relationship in MySQL?
Thank you for your time - if I've made anything unclear please let me know and I will try my best to clarify.
This includes genres, which have an (if I understand correctly) many
to many relationship with movies, implying a single movie can belong
to different genres and a single genre can belong to different movies.
That's right.
From what I gather about database design, storing this kind of
relationship in one table is not a good idea
Right. You're looking for something loosely along these lines.
create table movies (
movie_id integer primary key
-- other columns
);
create table genres (
genre varchar(15) primary key
-- other columns?
);
create table movie_genres (
movie_id integer not null,
genre varchar(15) not null,
primary key (movie_id, genre),
foreign key (movie_id) references movies (movie_id),
foreign key (genre) references genres (genre)
);
For directors, assuming there is only one director per movie, you can use this instead of the movies table above
create table movies (
movie_id integer primary key,
director_id integer not null,
foreign key (director_id) references directors (director_id) -- not shown.
-- other columns
);
You need one table Movies, one table Genres and one table Movies_and_Genres. The first two contain unique primary keys which you can create using the mysql autoincrement field type. The third table contains pairs of those primary keys.
create table movies (id integer not null primary key auto_increment, title ... );
create table genres (id integer not null primary key auto_increment, genre ... );
create table movies_and_genres (id_movie integer not null, id_genre integer not null);
As for the directors, this is a question of data modeling. If a movie can have more than one director, then you need a directors and a movies_and_directors table. Otherwise you need only the directors table and a director column in the movies table.
you need/should use junction tables
table movie:
| id | title | rating |
-----------------------
| 1 | foo | 5 |
| 2 | bar | 4 |
table genre:
| id | name |
----------------
| 1 | comedy |
| 2 | romance |
table director:
| id | name |
----------------
| 1 | hello |
| 2 | world |
table movie_genre:
| id | movie_id | genre_id |
----------------------------
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 2 | 1 |
table movie_director:
| id | movie_id | director_id |
-------------------------------
| 1 | 1 | 1 |
| 2 | 2 | 1 |
| 3 | 2 | 2 |
You're quite right, what you need here is to have a table of movies (e.g. tbl_movies);
pk id
name
... etc
a table for genres (eg tbl_genres);
pk id
name
... etc
and a table linking the two (eg tbl_movie_genres);
fk id_movies
fk id_genres
You can either set the pk of the tbl_movie_geners to be the two foreign keys, or you can set a standalone pk (e.g id like in the tbl_movies and tbl_genres tables above).
this way you can list as many genres per movies and they're linked through the tbl_movie_genres table; eg:
tbl_movies:
id name
1 Movie 1
2 Movie 2
tbl_genres:
id name
1 Horror
2 Action
3 Rom Com
tbl_movie_genres
id_movies id_genres
1 3
2 1
2 2
Would show you that 'Movie 1' is a rom com and 'Movie 2' is an action horror.
To satisfy the many-many relationship use a join table that holds foreign keys to both the movie and genre tables:
MOVIE
-----
ID (PK)
GENRE
-----
ID (PK)
MOVIE_GENRE
-----------
MOVIE_ID (FK that references MOVIE(ID))
GENRE_ID (FK that references GENRE(ID))
Here the MOVIE table has a primary key of ID, the GENRE table has a primary key of ID, and the MOVIE_GENRE table has two foreign key references: one to MOVIE.ID and another to GENRE.ID. The primary key for MOVIE_GENRE could either be the composite key of (MOVIE_ID,GENRE_ID) as that will be unique but you could use a synthetic key as well.
For dealing with the director table and relationship, if it is a one-to-many relationship (one director for many movies), simply add a foreign key to the MOVIE table:
DIRECTOR
--------
ID (PK)
MOVIE
-----
ID (PK)
DIRECTOR_ID (FK TO DIRECTOR(ID))
If the off chance you need to support another many-to-many relationship (many directors for many movies), use the join table approach like above.
I just want to know what is a parent table and what is a child table in databases. Can you please show me an example so I understand how it works please.
Thank You
Child tables and parent tables are just normal database tables, but they’re linked in a way that's described by a parent–child relationship.
It’s usually used to specify where one table’s value refers to the value in another table (usually a primary key of another table).
For example, imagine a news article. This could be represented by a table called articles and has fields for id, headline, body, published_date and author. But instead of placing a name in the author field, you could instead put the ID value of a user in a separate table—maybe called authors—that has information on authors such as id, name, and email.
Therefore, if you need to update an author’s name, you only need to do so in the authors (parent) table; because the articles (child) table only contains the ID of the corresponding author record.
Hope this helps you understand better.
Be aware you can have relationships that appear to be parent-child but are not, for instance when lookup tables are being used. The distinction is that in a true parent-child relationship, records typically don't stand are their own very well - they are detail records for the parent and are not useful without the parent table info. A person can own multiple cars in the DMV database, but you wouldn't want records in the CARS table without a parent record in the OWNERS table - it would be nearly useless data.
On the other hand, if I am using a lookup table to expand a code to something more meaningful, or to constrain data entry to acceptable values, then the "child" record can still useful (can stand alone) if the lookup table is deleted. I could still have the sex information as "M" or "F" even if I no longer have the lookup table to expand that to "Male" or "Female".
Parent - The entity on the "one" (/1) side of a relation with another table
Child - The entity on the "many" (/N/*) side of a relation with another table
A child table tends to be one where it has one or more foreign keys pointing at some other table(s). Note that a child table can itself be a parent to some OTHER table as well.
Those terms are used in database relationships.
for example u have two table,
1.Manifast
+-------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+------------------+------+-----+---------+----------------+
| manifast_id | int(11) unsigned | NO | PRI | NULL | auto_increment |
| description | text | NO | | NULL | |
| title | text | NO | | NULL | |
+-------------+------------------+------+-----+---------+----------------+
day_sequence
+-----------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+------------------+------+-----+---------+----------------+
| day_sequence_id | int(11) unsigned | NO | PRI | NULL | auto_increment |
| day_number | int(11) | NO | | NULL | |
| day_start | int(11) | NO | | NULL | |
| manifast_id | int(11) | NO | | NULL | |
+-----------------+------------------+------+-----+---------+----------------+
if u want to connect those two tables,u need to use the command with following format.
> ALTER TABLE child_table_name ADD FOREIGN KEY (P_ID) REFERENCES
> parent_table_name (P_ID)
and so it become.
> ALTER TABLE day_sequence ADD CONSTRAINT fk_manifast FOREIGN KEY
> (manifast_Id) REFERENCES manifast(manifast_Id);
In summary,
Child table is a table which has foreign key,and is connected from others table.
Parent table has no foreign key and connect to other.
[ Note : This ans is just for connecting two tables ]
I have two tables, books and authors. books has a author_id column and a secondary_author_id column (no books have more than two authors). I'm so far doing:
SELECT * FROM books
LEFT JOIN authors
ON books.author_id=authors.id
which is handling the join with the first author. I can't work out how I'd handle the secondary author though. Should I change my schema, or do I just need a bit of SQL help?
SELECT books.*, author1.*, author2.*
FROM books
LEFT JOIN author AS author1
ON author1.author_id = books.author_id
LEFT JOIN author AS author2
ON author2.author_id = books.secondary_author_id
In SQL, you can alias the tables by adding it after the table name. Just be careful, now you'll have duplicate columns, so instead of author1.* you will probably want to alias the results of both author1 and author2.
EDIT
Additional details -- Say you have your basic table (i'll include the details so if people want to test on their own they can):
CREATE DATABASE test;
USE test;
CREATE TABLE books
(
book_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(50),
author_id INT NOT NULL,
secondary_author_id INT
);
CREATE TABLE authors
(
author_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50)
);
INSERT INTO authors (author_id,name) VALUES (1,'Sue Z. Que'),(2,'John Doe'),(3,'Bob Smith');
INSERT INTO books (book_id,title,author_id,secondary_author_id) VALUES (1,'JOIN-ing Two Tables',1,2);
If you do the select I mention above, your result will be the following:
|----------------------- books TABLE -----------------------------|---- authors table -----|---- authors table ---|
+---------+---------------------+-----------+---------------------+-----------+------------+-----------+----------+
| book_id | title | author_id | secondary_author_id | author_id | name | author_id | name |
+---------+---------------------+-----------+---------------------+-----------+------------+-----------+----------+
| 1 | JOIN-ing Two Tables | 1 | 2 | 1 | Sue Z. Que | 2 | John Doe |
+---------+---------------------+-----------+---------------------+-----------+------------+-----------+----------+
(I've added the top header just for calrity's sake) you see you have two author_id's and two name's (as they are joins of the same table and same column names). BUT, if you alias the columns from the joins like so:
SELECT books.*, author1.name AS primary_author, author2.name AS secondary_author
FROM books
LEFT JOIN authors AS author1
ON author1.author_id = books.author_id
LEFT JOIN authors AS author2
ON author2.author_id = books.secondary_author_id;
You get a much cleaner result:
|----------------------- books TABLE -----------------------------| authors table -|- authors table --|
+---------+---------------------+-----------+---------------------+----------------+------------------+
| book_id | title | author_id | secondary_author_id | primary_author | secondary_author |
+---------+---------------------+-----------+---------------------+----------------+------------------+
| 1 | JOIN-ing Two Tables | 1 | 2 | Sue Z. Que | John Doe |
+---------+---------------------+-----------+---------------------+----------------+------------------+
SELECT books.* FROM books, authors.name, secondary_authors.name
LEFT JOIN authors
ON books.author_id=authors.id
LEFT JOIN authors as secondary_authors
ON books.secondary_author_id=secondary_authors.id
You need to rethink your design, because one day there will be a book with three authors, and the next day there will be a book with zero. (I've been there myself.)
Edit
As your comment says: yes, you need a books_authors table. As long as you have your indexes set up properly, it's not a big performance hit.
The most annoying part is that you're often going to want to string the authors together (one entry per book, concatenating all the authors into a single column). You'll probably end up creating a view for that.
just do another join on the secondary id