Relations between 3 mysql tables - php

I have 3 mysql tables: events, artists and (artist) descriptions. All of them are in many-to-many relations.
Table 'events':
ID | eventTitle | etc.
-----------------------
1 | event 1 |
2 | event 2 |
etc.
Table 'artists':
ID | artistName | etc.
-----------------------
1 | artist 1 |
2 | artist 2 |
etc.
Table 'descriptions':
ID | artistDesc | etc.
----------------------------------
1 | artist 1 description 1 |
2 | artist 1 description 2 |
3 | artist 2 description 1 |
4 | artist 2 description 2 |
5 | artist 3 description 1 |
etc.
I made also junction tables events_artists and artists_desctriptions. Both of them have only 2 foreign keys and serve only for linking event, artist and description IDs.
Notice in my descriptions table - each artist can have many descriptions. That actually means that each description belongs to only one specific event. =)
If I do a query like this:
$q = "SELECT
events.*,artists.*,descriptions.*,events_artists.*,artists_descriptions.*
FROM
events,artists,descriptions,events_artists,artists_descriptions
WHERE
events.eventID = events_artists.eventID AND
events_artists.artistID = artists.artistID AND
artists.artistID = artists_descriptions.artistID AND
artists_descriptions.descID = descriptions.descID";
I will get all the descriptions for a particular artist. But none of descriptions will be aware which event they belong to...
What I want to display to user is something like this:
EVENT 1
artist 1 (artist 1 description 1)
artist 2 (artist 2 description 2)
EVENT 2
artist 3 (artist 3 description 6)
artist 1 (artist 1 description 3)
etc.
Should I make a junction table for event-description relation? If I do, I don't know exactly how to use it, uff! =)
Or maybe my problem isn't solvable with a simple query? Should I do something with php too? Sorry but I am totally confused =)
I hope I managed to explain my problem properly...
Thanks in advance for any help!

you should combine events_artists & descriptions tables to have only 1 table that links artist to an event and a description.

Can you modify the tables you already have? If so, and if each artist description can have only one artist and one event, then I would modify your schema to be:
Table event as is.
Table artists as is.
Table descriptions:
ID | artistDesc | artistId | eventId | etc.
------------------------------------------------------------------
1 | description of artist at event | 4 | 1 | ...
Then you can select all descriptions for an event with:
$query = "SELECT
events.*,artists.*,descriptions.*
FROM
events,artists,descriptions
WHERE
artists.artistID = descriptions.artistID AND
events.eventID = descriptions.eventID AND
events.eventID = $eventIdYouWant";
You can change the last row of that query to either events.event_name = $eventNameYouWant or artists.artist_name = $artistNameYouWant and it will work the same as if you were directly specifying the id.

you have already said its a relation between 3 tables .. so i think the answer is pretty obvious .. you need to have 1 table artist_id , event_id and description_id in ONE table instead of diving that into two tables like u have now.

I think you should alter your table structure, if you can.
It will result in a neater design.
Make a table, artist_event_description which contains all the IDs as foreign keys, instead of the two junction tables, it will help you to find out, to which event and artist a description belongs.
Another thing you can do is to include two more columns in the Description table, eventId and artistId (these will be foreign keys) and remove the junction tables. This way you will directly get all the information you need by just doing a SELECT over the description table.

Related

Replace value with Foreign Key's result

I have a table with all my invoice items as packages:
Table: invoice_items
invoice_item_id | package_id | addon_1 | addon_2 | addon_3 | ...
----------------|------------|---------|---------|
1 | 6 | 2 | 5 | 3 |
Then my other table:
Table: addons
addon_id | addon_name | addon_desc |
----------|--------------|--------------------------|
1 | Dance Lights | Brighten up the party... |
2 | Fog Machine | Add some fog for an e... |
Instead of taking up space storing the addon name in my invoice_items table, I'd like to just include the addon_id in the addon_1, addon_2, etc columns.
How do I then get the name of the addon when doing a query for invoice_item rows?
Right now I just have it programmed into the page that if addon_id == 1, echo "Dance Lights", etc but I'd like to do it in the query. Here is my current query:
$invoice_items_SQL = "
SELECT invoice_items.*, packages.*
FROM `invoice_items`
INNER JOIN packages ON invoice_items.invoice_item_id = packages.package_id
WHERE `event_id` = \"$event_id\"
";
So I'm able to do this with packages, but only because there's just one package_id per row, but there are up to 9 addons :(
The most direct way of doing it is to join onto the table multiple times. That's a bit naff though because you'll write almost the same thing 9 times.
Another, better way would be to restructure your tables - you need another table with 2 data columns: invoice_id and addon_id. You then need either an auto-inc primary column, or use both of those existing columns as a dual primary key. So this is a many-to-many junction table.
From there you can can query without having 9 repetitive joins, but you will get a row of each package for every addon it has (so if it has three addons it will appear three times in the results). And then from there you can use GROUP_CONCAT to concatenate the names of the addons into a single field so that you only get one row per invoice.

Benefit of additional tables

I have a product page which displays a user's comment, name and rating of the particular product. These values are stored in my data base as such "Id, name, comment, rating"
Now I find myself struggling if I want to store comments,name and rating from all product pages into one table as the output would display comments, name and ratings on every page which I don't want.
Am I correct in trying to pursue this one table theory? Or should I just go ahead and make a seperate table for each product page?
Your comments can go in a single table, you should however store the identifier of the product, so you can filter the comments. Example:
+------------+------------+------+-----------------+
| comment_id | product_id | name | comment |
+------------+------------+------+-----------------+
| 1 | 1 | john | Cool product! |
| 2 | 2 | jack | Don't like this |
| 3 | 1 | jack | Nice! |
...
Now if you want to display all comments for the product with id 1, you would execute this query:
SELECT * FROM `comments` WHERE `product_id` = 1
There you go! You have john's comment, and jacks comment which says "Nice!"

How to select records in mysql based from array of category id?

I have a table where the table has a category field is array value
LIKE :
|-----------------------------------|
|post_id | name | category_id |
-------------------------------------
|1 | test1 | 1,2,45 |
|2 | test2 | 2,7 |
|3 | test3 | 7,13,56 |
|-----------------------------------|
From drop down select box if i select CATEGORY ID 2. i should get the result of TWO ROWS. because post_id 1 and 2 have 2 in category_id. i don't know how to do query for it. i struggled a lot. please help me out. Thanks in advance.
If posts can be in multiple categories, then you should reconsider the use of arrays in the category_id field, and instead use a post/category reference table, with a structure such as:
id postId catId
This way, you can get all posts in category 2 by (lets call this reference table 'PostCats'):
SELECT postId FROM PostCats WHERE catId=2
There is a simple way to sort this out.
You can change the datatype of category_id to SET and using something like this:
SELECT * FROM table WHERE FIND_IN_SET('2', category_id);
Read more: FIND_IN_SET
Also look at flauntster' answer for the most appropriate way to do it.

How to post a movie into different categories with php?

Suppose I have a movie listing website and I want post a movie into different categories (eg: Drama , Action) And these categories should come from another table so that i can show a particular movie in two or more categories . how is it possible ?
What you are looking for, I believe is a many-to-many table relationship. You would have a table containing all of your movies (their names, duration, etc). And another table containing a list of all possible categories (action,drama,comedy,etc).
The trick will be to have an additional third table containing the movie to category relationship. You reference the movie's id and the category id, like this -
id | movie_id | category_id
---|----------|-------------
1 | 1 | 1
2 | 1 | 2
3 | 2 | 3
4 | 2 | 1
In this example, movie id 1 is in category 1 and 2. Movie id 2 is in category 1 and 3. So you see, a movie can be in more than one category.
You build a table that holds movie ids and category ids:
movie_category(movie_id*,category_id*)
'*' = (component of) PRIMARY KEY

Reorder/reset column unique id in mysql

I do not know a lot of mysql. I have two tables on same server:
A.artists
id | artist_name
--------------------
8 | XXXX |
1 | YYYY |
5 | ZZZZ |
A.albums
id | artist_id | album_name
-----------------------------
1 | 5 | Album 1
2 | 1 | Album 2
3 | 8 | Album 3
I want to reorder the artist_id column, accordingly, at the same time I want to change A.artists's id column from reordered artist_id id.
Is it possible such a thing? How can I do that? Thanks!
First, you need to understand that tables in SQL are unordered. So, you cannot specify an ordering for the table. You can specify an ordering for a query.
My guess is that you want to join the two tables to get the name with the albums:
select al.*, ar.name
from albums al join
artists ar
on al.artist_id = ar.id
order by ar.name
The way your question is phrased is that you want to re-assign ids. Normally, this would not be necessary, since the ids exist only to uniquely identify rows. If you have a good reason for reassigning ids, then modify your question or ask a new question, including the reason.

Categories