My 3 tables:
posts
tags:
post2tags:
So in the posts
table I did not reference anything related to tags
. And in the tags
table, no reference for posts
. I created a new table, posts2tags
and referenced the posts
for tags
there.
Question: Is this the proper way to do it? Do I need to have any reference for posts
in tags
table and vice versa?
What I want to achieve is to return everything from the posts
table and all tag
names
where the post
is referenced for tags
(in posts2tags
table) and have all the tag names
in an array/single row
in the result. Like this:
Tried :
SELECT p.idPost, p.title, t.name from posts as p, tags as t, post2tags
WHERE t.idTags=post2tags.idTags
Result:
I'm learning to join multiple tables and reduce the table to only required information from it. So looking for advice on that too.
Yes its the right way to store ManyToMany
relation the junction table (post2tags) will hold the references for posts and tags to relate them. To get the expected results you can use left join to get all posts whether they have tags or not
select p.idPost, p.title, t.name
from posts as p
left join post2tags pt on (p.idPost = pt.idPost)
left join tags t on (t.idTags = pt.idTags)
order by p.idPost
this will return you all the post with their related tags, Each will be returned multiple times as no. of assigned tags like
idPost title name
-------------------
1 test tag1
1 test tag2
2 test tag1
2 test tag2
3 test null
then in application code you can display these results as per you desired format by doing some if/else logic to show post once only and display its tags.
Another hacky way would be use of group_concat
function which returns comma separated list of values per group like below but it has some limitation of character length.
select p.idPost, p.title, group_concat(t.name) as `name`
from posts as p
left join post2tags pt on (p.idPost = pt.idPost)
left join tags t on (t.idTags = pt.idTags)
group by p.idPost
order by p.idPost
this will give you results as per your desired view
idPost title name
-------------------
1 test tag1,tag2
2 test tag1,tag2
3 test null