I have two tables: Employee and Training, Employee table has two columns: ID (numeric) and Name (text).
Training table also has two columns: No (numeric) and TrainingName (text).
My boss asked me the following:
Some trainingName can be classified by “group name” (group name can dynamically be added by user input) and one traininName can be classified in one group, no group or more than one group. Each employee can be under one group or no group.(can not be under two or more groups).
I am confused in how to manage that? Do I need to create another table or modify the existing tables?
I am using PostgreSQL9.2.
You'll need to add two more tables: "groups", and "groups_trainings".
This will be your resulting Database-Layout:
employees:
id
name
group (foreign key to groups.id; can be null)
trainings:
id
trainingName
groups:
id
groupName
groups_trainings
id
trainingID (foreign key to trainings.id)
groupID (foreign key to groups.id)
You need the last table, to map n groups to n trainings.
The layout says the following:
Each empoyee belongs to one group, or no group (employees.group is null)
Each group can contain 0 or more trainings.
Each training can be part of 0 or more groups
Related
I have 3 tables in PostgreSQL database:
person (id, first_name, last_name, age)
interest (id, title, person_id REFERENCES person)
location (id, city, state text NOT NULL, country, person_id REFERENCES person)
city can be null, but state and country cannot.
A person can have many interests but only one location. My challenge is to return a table of people who share the same interest and location.
All ID's are serialized and thus created automatically.
Let's say I have 4 people living in "TX", they each have two interests a piece, BUT only person 1 and 3 share a similar interest, lets say "Guns" (cause its Texas after all). I need to select all people from person table where the person's interest title (because the id is auto generated, two Guns interest would result in two different ID keys) equals that of another persons interest title AND the city or state is also equal.
I was looking at the answer to this question here Select Rows with matching columns from SQL Server and I feel like the logic is sort of similar to my question, the difference is he has two tables, to join together where I have three.
return a table of people who share the same interest and location.
I'll interpret this as "all rows from table person where another rows exists that shares at least one matching row in interest and a matching row in location. No particular order."
A simple solution with a window function in a subquery:
SELECT p.*
FROM (
SELECT person_id AS id, i.title, l.city, l.state, l.country
, count(*) OVER (PARTITION BY i.title, l.city, l.state, l.country) AS ct
FROM interest i
JOIN location l USING (person_id)
) x
JOIN person p USING (id)
WHERE x.ct > 1;
This treats NULL values as "equal". (You did not specify clearly.)
Depending on undisclosed cardinalities, there may be faster query styles. (Like reducing to duplicative interests and / or locations first.)
Asides 1:
It's almost always better to have a column birthday (or year_of_birth) than age, which starts to bit-rot immediately.
Asides 2:
A person can have [...] only one location.
You might at least add a UNIQUE constraint on location.person_id to enforce that. (If you cannot make it the PK or just append location columns to the person table.)
I have a table which stores information about a group. Information such as the group name, group id, the number of members... However, I would also like to store the codes of each individual member within a group.
The way I initially tried to store the member codes was by creating individual columns. So I would have columns named MemberCode1, MemberCode2, MemberCode3. But the problem is a group can have 100 members which would mean 100 columns would be required to store the member codes individually.
My question: is there a way I can store an x amount of member codes within a single column within my table, or do simply make y columns and limit the number of users in a group to y?
This is a great example of when to use a separate table. You can create a second table, called "group", and store your group data there (group ID, group name).
I'm assuming that a member can belong to multiple groups, and a group can have many members.
If so, you can then have a table in the middle of those two tables to capture the members in each group. You can call this table "memberships" or "group_member" or something.
It would contain the Primary Keys of each of the entries in the member and group tables.
So your table structure could be:
MEMBER (member ID... other fields)
GROUP (group ID, group_name)
MEMBERSHIP (member_id, group_id)
Finally, to find the number of members in each group:
SELECT group_id, COUNT(*)
FROM membership
GROUP BY group_id;
Or to get group data with that:
SELECT m.group_id, g.group_name, COUNT(m.*)
FROM membership m
INNER JOIN group g ON m.group_id = g.group_id
GROUP BY m.group_id;
Generally speaking it is not a good idea to store multiple pieces of information in the same field. It violates normal form and, more practically, it is hard to maintain.
The best solution to your issue would be to create a separate table for the members (Member) and include a foreign key, perhaps groupID or group_id, referring to the group table (Group).
In the event that a "member" can belong to more than one "group", you would create a third table, MemberGroup, with a composite primary key (member_id, group_id) made up of foreign keys referring to Member and Group respectively.
I have multiple (8-10) different datasets, all of which have a primary key (Name), some common columns and then some individual columns each. For example, table 1 might consist of Name, Date, Age, Username, LoginTime; table 2 Name, Date, MothersName,LoginTime, Age; table3 Name, Username, School, University, Age and so on and so forth.
Ideally I would like this all merged into a single table with unique columns: Name, Date, Age, Username, LoginTime, MothersName, School, University.
I know Access doesn't allow the use of covalesce - how can I go about creating this master table? I know what order I would like SQL to look in i.e. if Age is not in table 3, only then look in table 2 (even if table 2 has a value), and only then look in table 1 for that given Name. However I cannot work out how best to do the join so I don't get table1.Age, table2.Age, and table3.Age across all of my common fields...
I want to concat group name with the number of the students of the group with another parameter to select groups from Groups table
Like this :
Group1 -- 250 std
Group2 -- 243 std
Groups and students are separated tables and foreign key in Groups table used to select target groups
I have a two tables one of them has std data with group Id as foreign key and groups table has groups data and a foreign key for subject
I need to get all the groups which coresponding with subject id I want and count the std of each group ,concat it with the group name
Read about SQL Joins here
https://www.w3schools.com/sql/sql_join.asp
A join retrieves columns from different tables by relating two rows using an ON clause
I have two tables. One is a 'Users' table. Each row (user) in the table has a unique id (primary key).
The second table is a 'Tasks' table. Each row in the Tasks table has a foreign key which points to the user (in the Users table) that owns that task.
Using SQL Express 2008, what query must I use to obtain a list of all tasks assigned to a user? For example, if I have a user in the Users table with a primary key of 0 and there are 10 rows in the Tasks table with a foreign key value of 0, that means that this user has 10 tasks assigned to him. I need to build a query that gives me these 10 rows from the Tasks table.
If you have the user PK
select tasks.*
from tasks
where tasks.UserId = 0
if you have the user name
select tasks.*
from tasks
inner join users on users.UserId = tasks.UserId
where users.UserName = 'Bob'
Are you just looking for a simple filter?
SELECT * FROM tasks WHERE userid=0
I think you can achieve what you want with a simple single table select, assuming you know the id of the user:
SELECT *
FROM Tasks
WHERE user_id = 1234