Something like the following should work for you:
SELECT tags.*, tagnames.tag AS sessionname
FROM tags
INNER JOIN
(SELECT sessionid, tag
FROM tags WHERE counter = 2) AS tagnames
ON tags.sessionid = tagnames.sessionid
This method works by creating a table that consists only of the session identifier and the name (this is the INNER JOIN subquery) which we then join back on to the main set to allow us to bring in the session name as a distinct column.
It makes two assumptions:
- The
INNER JOIN
specifies that we always expect there to be a name for our session - The name tag will always be identified with a session id having
counter = 2
EDIT:
From your comment, I see we cannot identify the name row by having counter = 2
BUT it will always be the second
row for a given sessionid. Therefore, we can do the following to pick out the 2nd row per sessionid:
SELECT @previous_session := null;
SELECT
sessionid,
counter,
tag,
@counter_rank := IF(@previous_session = sessionid, @counter_rank + 1, 1) AS counter_rank,
@previous_session := sessionid
FROM tags
ORDER BY sessionid, counter ASC
This generates an "artifical" row number using a user defined variable per session group so we can always locate the second record sorted by sessionid and counter.
Incorporating this into the first query gives us:
SELECT @previous_session := null;
SELECT tags.*, tagnames.tag AS sessionname
FROM tags
INNER JOIN
(SELECT countranks.sessionid, countranks.tag
FROM (
SELECT
sessionid,
counter,
tag,
@counter_rank := IF(@previous_session = sessionid, @counter_rank + 1, 1) AS counter_rank,
@previous_session := sessionid
FROM tags
ORDER BY sessionid, counter ASC
) AS countranks WHERE countranks.counter_rank = 2
) AS tagnames
ON tags.sessionid = tagnames.sessionid;
Here's the sql in action