954,600 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

how to make LIMIT on contents join X TAGS?

hello, I need to display contents with their tags, and in same page all the tags of the page contents
the problem is having a limit on contents doesn't work if join tags on them (the number of tags change the number of select contents)

THE TABLES
==========

I have tables :

> contents
> tags
> link_contents_tags (id_tag, id_content)


I need to select contents with tags so for each content I display its tags
I have a pager so I limit the select of contents

the problem is if I make a
> select contents JOIN tags LIMIT xcontents
it won't work because of the y number of tags on each content
and to limit the number of tags is not a solution because it's unkwnown number (it can have no tag or 10)EXAMPLE
=======

so limit of 3 contents must display :

CONTENTS:
> <strong>content_1 </strong>
>> tag1_content1
>> tag2_content1
>> tag3_content1

> <strong>content_2</strong> 
>> (no tags)

> <strong>content_3 </strong>
>> tag1_content3

TAGS:
tag1_content1
tag2_content1
tag3_content1
tag1_content3


but if I set
LIMIT 0, 3
on select contents join tags it'll not display 3 contents but just the first because of the join on x tagsA (not beautiful) SOLUTION
==========================

a solution is to

> select contents with search criterias
> read ids of found contents
> select tags JOIN links WHERE id_content IN (list ids found contents) ORDER BY id_content
> order tags in an array by content_id : arTags[content_id]=array rows tags
> display all contents, for each content display tags from tags array if exist 
> display next all contents from this page


it'll work with contents pager and unknown tags number by content
but it seems a little rude :)
two requests (can be ok) but a few loops on contents that I don't like

have any idea to simplify it?
I don't like to make ugly code :)

think's in advance

davehere
Newbie Poster
5 posts since Dec 2010
Reputation Points: 10
Solved Threads: 0
 

You can limit the paged entries in a SELECT DISTINCT clause like that: drop table if exists a;
drop table if exists b;
drop table if exists ab;
create table a (id integer);
create table b (id integer);
create table ab (a_id integer, b_id integer);
insert into a values (1),(2),(3),(4),(5);
insert into b values (1),(2),(3),(4),(5);
insert into ab values (1,1),(1,2),(1,3),(2,1),(2,2);

/* page 1 */
select a.*, b.*
from a
inner join (
select distinct a_id from ab order by a_id limit 0,1
) x
on a.id=x.a_id
inner join ab
on a.id=ab.a_id
inner join b
on ab.b_id=b.id
;
+------+------+
| id | id |
+------+------+
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
+------+------+

/* page 2 */
select a.*, b.*
from a
inner join (
select distinct a_id from ab order by a_id limit 1,1
) x
on a.id=x.a_id
inner join ab
on a.id=ab.a_id
inner join b
on ab.b_id=b.id
;
+------+------+
| id | id |
+------+------+
| 2 | 1 |
| 2 | 2 |
+------+------+

smantscheff
Nearly a Posting Virtuoso
1,233 posts since Oct 2010
Reputation Points: 300
Solved Threads: 254
 

If the tags are for displaying only, wouldn't a GROUP_CONCAT be useful ?

pritaeas
Posting Expert
Moderator
5,484 posts since Jul 2006
Reputation Points: 653
Solved Threads: 875
 

hey think for your quick - and good - responses ! :)

Smantscheff big think to have taken time to write complate example, it learns me better use to select distinct

and, wahou think pritaeas it's so beautiful! :)

so I'll use

GROUP_CONCAT(tag.name) as tags_names, GROUP_CONCAT(tag.type) as tags_types
...
GROUP BY content.id


and after in php explode on tags_names and tags_types to have them
there'll be a little time price in group by and working array but I think I won't find more simple

think you two you made my week!

davehere
Newbie Poster
5 posts since Dec 2010
Reputation Points: 10
Solved Threads: 0
 

I have also to get count contents of tags (a column in tags with update +1 when a new content on it) and order on count, but these works :

GROUP_CONCAT(tag.name ORDER BY tag.count_contents DESC) as tags_names, 
GROUP_CONCAT(tag.typename  ORDER BY tag.count_contents DESC) as tags_types, 
GROUP_CONCAT(CAST(tag.count_contents AS CHAR) ORDER BY tag.count_contents DESC) as tags_counts, 
...
JOIN tags
...
GROUP BY node.id


result :

content   | tagname          |  tagcount | ...
the clash | music rock punk  | 20 14 8


with for each content get its tags order by count of all contents on tags
(here there is a lot of contents on music, some on rock and a few on punk)


is it right for performing, or is it bad practice to have these 3 group_concat?

I'll have work on server to manage array of tags by contents but I think I can't avoid it (because in all cases I'll have to extract tags array from each content row)

think! :)

davehere
Newbie Poster
5 posts since Dec 2010
Reputation Points: 10
Solved Threads: 0
 

well I have found it I think it's ok with only one group_concat

GROUP_CONCAT(CONCAT(tag.typename,','), CONCAT(tag.name,','), CAST(tag.count_contents AS CHAR) ORDER BY tag.count_contents DESC SEPARATOR ';') as tags,


I think it's better performing with just one group_concat

davehere
Newbie Poster
5 posts since Dec 2010
Reputation Points: 10
Solved Threads: 0
 

This question has already been solved

Post: Markdown Syntax: Formatting Help
You
View similar articles that have also been tagged: