skip to Main Content

My goal is to get a result where it will output all exercise entries, with a single related video, then a concatenated string of all associated tags (where tags is one table and tag_linkage is how the tags relate to the exercises).

Ideal end result:

My Exercise Name, Somepath/video.mp4, TagName1|TagName2|TagName3
Another Exercise Name, Somepath/video.mp4, TagName2|TagName5|TagName6
and so on...

I have this for the structure:

CREATE TABLE `exercises` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) CHARACTER SET latin1 DEFAULT NULL,
  `video_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
)

CREATE TABLE `videos` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `filename` varchar(255) CHARACTER SET latin1 DEFAULT NULL,
  PRIMARY KEY (`id`)
)

CREATE TABLE `tags` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) CHARACTER SET latin1 DEFAULT NULL,
  PRIMARY KEY (`id`)
)

CREATE TABLE `tag_linkage` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `exercise_id` int(11) DEFAULT NULL,
  `tag_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
)

And this is my query thus far:

SELECT 
exercises.name AS Exercise, 
videos.filename AS VideoName, 
tags.name as Tag,
FROM exercises
  INNER JOIN tag_linkage AS tl ON  exercises.id = tl.exercise_id
  INNER JOIN tags ON tags.id = tl.tag_id 
    LEFT JOIN videos
    ON exercises.video_id = videos.id    
    ORDER BY exercises.id 
    LIMIT 20000 
    OFFSET 0;

The join on the tags is where I’m stuck. The tag_linkage table has an exercise_id and a tag_id. I need to be able to use the exercises.id as a join on tag_linkage.exercise_id but return the tag.name from another table, but I cannot figure out how to approach it. The current query above gives me Tag as a column in the results, but each tag is a new row:

My Exercise Name, Somepath/video.mp4, TagName1
My Exercise Name, Somepath/video.mp4, TagName2
My Exercise Name, Somepath/video.mp4, TagName3
Another Exercise Name, Somepath/video.mp4, TagName1
Another Exercise Name, Somepath/video.mp4, TagName3
Another Exercise Name, Somepath/video.mp4, TagName5
and so on...

I want to remove the duplicate rows and concatenate the tags into 1 column.

Edit: Figured it out.


SELECT 
exercises.name as Exercise, 
videos.filename AS VideoName, 
GROUP_CONCAT(DISTINCT(tags.name)  separator ', ') Tags,
FROM exercises
LEFT JOIN videos
ON exercises.video_id = videos.id
JOIN tag_linkage ON exercises.id = tag_linkage.exercise_id
JOIN tags ON tags.id = tag_linkage.tag_id
GROUP BY exercises.name
LIMIT 1000
OFFSET 0;

2

Answers


  1. Chosen as BEST ANSWER

    Figured it out:

    SELECT 
    exercises.name as Exercise, 
    videos.filename AS VideoName, 
    GROUP_CONCAT(DISTINCT(tags.name)  separator ', ') Tags,
    FROM exercises
    LEFT JOIN videos
    ON exercises.video_id = videos.id
    JOIN tag_linkage ON exercises.id = tag_linkage.exercise_id
    JOIN tags ON tags.id = tag_linkage.tag_id
    GROUP BY exercises.name
    LIMIT 1000
    OFFSET 0;
    

  2. You need to join tags separately

    SELECT 
    exercises.name AS Exercise, 
    videos.filename AS VideoName, 
    files.name as FileName, 
    GROUP_CONCAT(tags.name SEPARATOR '|') AS Tags
    FROM exercises
      INNER JOIN tag_linkage AS tl ON  exercises.id = tl.exercise_id
      INNER JOIN Tags  ON Tags.id = tl.tag_id 
        LEFT JOIN videos
        ON exercises.video_id = videos.id
        LEFT JOIN files
        ON exercises.file_id = files.id
        
    
        ORDER BY exercises.id 
        LIMIT 100 
        OFFSET 0;
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search