I have a single flat table containing a list of people which records their participation in different groups and their activities over time. The table contains following columns:
- name (first/last)
- e-mail
- secondary e-mail
- group
- event date
+ some other data in a series of columns, relevant to a specific event (meeting, workshop).
I want to extract distinct people from that into a separate table, so that further down the road it could be used for their profiles giving them a list of what they attended and relevant info. In other words, I would like to have a list of people (profiles) and then link that to a list of groups they are in and then a list of events per group they participated in.
Obviously, same people appear a number of times:
| Full name | email | secondary email | group | date |
| John Smith | jsmith#someplace.com | | AcOP | 2010-02-12 |
| John Smith | jsmith#gmail.com | jsmith#somplace.com | AcOP | 2010-03-14 |
| John Smith | jsmith#gmail.com | | CbDP | 2010-03-18 |
| John Smith | jsmith#someplace.com | | BDz | 2010-04-02 |
Of course, I would like to roll it into one record for John Smith with both e-mails in the resulting People table. I can't rule out that there might be more records for same person with other e-mails than those two - I can live with that. To make it more complex ideally I would like to derive a list of groups, creating a Groups table (possibly with further details on the groups) and then a list of meetings/activities for each group. By linking that I would then have clean relational model.
Now, the question: is there a way to perform such a transformation of data in SQL? Or do I need to write a procedure (program) that would traverse the database and do it?
The database is in MySQL, though I can also use MS Access (it was given to me in that format).
There is no tool that does this automatically. You will have to write a couple queries (unless you want to write a DTS package or something proprietary). Here's a typical approach:
Write two select statements for the two tables you wish to create-- one for users and one for groups. You may need to use DISTINCT or GROUP BY to ensure you only get one row when the source table contains duplicates.
Run the two select statements and inspect them for problems. For example, it's possible some users show up with two different email addresses, or some users have the same name and were combined incorrectly. These will need to be cleaned up in order to proceed. There is great way to do this-- it's more or less a manual process requiring expert knowledge of the data.
Write CREATE TABLE scripts based on the two SELECT statements so that you can store the results somewhere.
Use INSERT FROM or SELECT INTO to populate the tables from your two SELECT statements.
I have two table now:
conference table: id, name
people table: people_id, name
what I want to do
I want to make a new table so that I can get all attend people by conference id but also get all conference a specific man attended by people_id.
what I have thought
make a new table whose columns is all the people's id, and insert each conference as row, if the people shows in conference, we make it 1, otherwise 0. But it's too sparse and difficult to show which people attend a specific conference because we have many columns.
UPDATE
thanks for your comment. Now I create a table like this:
I think it's much better than the table before.
How about this?
A join table called conferences_people.
cp_id | conference_id | people_id
-------+---------------+-----------
1 | 1234 | 1
2 | 1234 | 4
3 | 1234 | 5
my rule of business is something like a used car/motobike dealership:
My table "stock" contains cars, so no two of the same products as each automobile belongs to a different owner.
Sometimes the owner has two cars that he wants to sell separately, but also wants to sell them together, eg:
Owner has a car and a motorcycle:
+----------------+
| id | Stock |
+----+-----------+
| 1 | car |
+----+-----------+
| 2 | motorcycle|
+----+-----------+
In case he wants to advertise or sell in two ways, the first would be the car for U$10.000 and motobike for U$5.000
But it also gives the option to sell both together for a lower price (car + bike U$ 12.000), eg:
+----+-----------+--------------------+-----------+
| id | id_poster | Stock | Price |
+----+-----------+--------------------+-----------+
| 1 | 1 | car | U$ 10.000 |
+----+-----------+--------------------+-----------+
| 2 | 2 | motorcycle | U$ 5.000 |
+----+-----------+--------------------+-----------+
| 1 | 3 | car | U$ 12.000 |
+----+-----------+--------------------+-----------+
| 2 | 3 | motorcycle | U$ 12.000 |
+----+-----------+--------------------+-----------+
This is the best way to do this?
My structure is already doing so (just as I believe to be the best way), I'm using foreign key and n:m, see my structure:
Ok, so if I'm understanding the question right, you're wondering if using a junction table is right. It's still difficult to tell from just your table structures. The poster table just has a price, and the stock table just has a title and description. It's not clear from those fields just what they're supposed to represent or how they're supposed to be used.
If you truly have a many-to-many relationship between stock and poster entities -- that is, a given stock can have 0, 1 or more poster, and a poster can have 0, 1 or more stock -- then you're fine. A junction table is the best way to represent a true many-to-many relationship.
However, I don't understand why you would want to store a price in poster like that. Why would one price need to be associated with multiple titles and descriptions? That would mean if you changed it in one spot that it would change for all related stock. Maybe that's what you want (say, if your site were offering both A1 and A0 size posters, or different paper weights with a single, flat price across the site regardless of the poster produced). However, there just aren't enough fields in your tables currently to see what you're trying to model or accomplish.
So: Is a junction table the best way to model a many-to-many relationship? Yes, absolutely. Are your data entities in a many-to-many relationship? I have no idea. There isn't enough information to be able to tell.
A price, in and of itself, may be one-to-one (each item has once price), one-to-many (each item has multiple prices, such as multiple currencies), or -- if you use a price category or type system like with paper sizes -- then each item has multiple price categories, and each price category applies to multiple items.
So, if you can tell me why a stock has multiple prices, or why a single poster price might apply to multiple stock, then I can tell you if using a junction table is correct in your situation.
Having seen your edit that includes your business rules, this is exactly the correct structure to use. One car can be in many postings, and one posting may have many cars. That's a classic many-to-many, and using a junction table is absolutely correct.
Not clear how the examples relate to your diagram because you use different terminology, but I think it's safe to say: If you want to store something like "this entity consists of orange, apple and pear" then the DB design you show is the correct way to do it. You'd have one poster entry, and three entries in the poster_has_stock pointing to the same poster and three elements in stock.
The structure which you're using is best solution in your case, no need to change, just 2 minor changes needed:
1. remove 2 indexes: fk_poster_has_stock_stock1_idx and fk_poster_has_stock_poster_idx, because they are primary keys already
2. stock_price field should use decimal data type (more precise)
You can read more about Decimal data type here
I think Your solution is nearly perfect. I think You may add "id" to "poster_has_stock" table. And of course change price type (it was written upper).
But You may consider second option with stock_id in poster table.
WHY?
-There should be no poster with no stock connected to it.
-In most cases there will be offers: one stock <=> one poster
This will allow You also to add as many dependend stocks to poster as You want.
You can also add poster_special_price DECIMAL (9,2) to poster table.
This will allow You easy to show:
price for stock item.
Special price for stock item with it's dependencies.
This will be also easier to manage in controller (create, update) - You will be adding poster already with stock, No transactions will be needed during adding new poster.
you may consider a new table that creates a relationship between the stock items such as:
stock_component
---------------
parent_stock_id
child_stock_id
child_qty
in this way, you can link up many children into one parent in the style of a bill of materials, then the rest of your links can continue to be simply related to stock_id of the appropriate parent.
Still working on a web application as a school project, and it just seems to keep expanding.
I have to add a layer for teachers so they can manage and coach students through the application. So, I have to link teachers to their students.
I was wondering what the best way would be to do this. I have one table for all users at the moment. The bare basics of this table are:
id | email | firstname | lastname | role
1 | s#s.s | dromiceio | mimus | 1
2 | d#d.d | tyranno | saurus | 2
3 | a#a.a | utah | raptor | 1
Role is the number I assign to them to give them certain permissions. 1 = student, 2 = teacher, 3 = admin.
Assuming that one student has one teacher but one teacher has many students, what would be the best way to design my database table?
I was thinking of creating a new table and just putting the student/teacher ids in it:
For example, if teacher Tyranno Saurus (id 2) has the two students in the table above linked to him, I would make a table like this:
pk_id | teacherid | studentid
1 | 2 | 1
2 | 2 | 3
That way, I would know that teacher Tyranno (id 2) has two students, namely the student with userid 1 and userid 3.
Then again, I have never really worked on anything like this so I was wondering if anyone could give me some insight about this and if it's possible to do this in a better way.
I'm building my app in PHP (CodeIgniter) with MySQL; if that's of importance.
Thanks a lot.
If a student has zero-or-one teacher coaching them, then I would suggest adding a CoachID column to the student table that is a foreign-key to that particular teacher. The intermediate table you've suggested doesn't do anything to simplify this simple relationship, it actually makes it that little bit more complicated.
If you were tying students to classes (where each class has multiple students and each student takes multiple classes) then an intermediate many-to-many mapping table would be a must.
the question is :
i have a table that contains details, this table is used by users when they registered or update there profile or participate in different exams.
The report I need will have some calculation like aggregate scores .
I would to as if it is better to create new table witch includes the report i need or it's better to work on the same table.
Are you able to provide any further details? What fields are available in the table that you want to query? How do you want to display this information? On a website? For a report?
From what you describe, you need two tables. One table (lets call is 'users') would contain information about each user, and the other would contain the actual exam scores (lets call this table 'results' ).
Each person in the 'user' table has a unique ID number (I'll call it UID) to identify them, and each score in the 'results' table also has the UID of person the score relates to. By including the UID of the user in the 'results' table you can link an infinite number of results (known as a one-to-many relationship).
The 'user' table could look like this:
userUID (UID for each person) | Name | User Details
1 | Barack Obama | President
2 | George Bush | Ex-President
The 'results' table could look like this:
UID for each exam | userUID (UID of the person who look the test) | Score
1 | 1 | 85
2 | 2 | 40
3 | 1 | 82
4 | 2 | 25
I always like to add a UID for things like the exam because it allows you to easily find a specific exam result.
Anyway... a query to get all of the results for Barack Obama would look like this:
SELECT Score From 'results' WHERE userUID = 1
To get results for George Bush, you just change the userUID to 2. You would obviously need to know the UID of the user (userUID) before you ran this query.
Please note that these are VERY basic examples (involving fictional characters ;) ). You could easily add an aggregated score field to the 'user' table and update that each time you add a new result to the 'results' table. Depending upon how your code is set up this could save you a query.
Good luck - Hopefully this helps!