SELECT bookmarks.url
, m.dupes
, bookmarks.title
, SUBSTR(bookmarks.snippet, 1, 100) as snippet
, bookmarks.datetime
, [COLOR="Red"]t.tags[/COLOR]
, [COLOR="Blue"]l.users[/COLOR]
FROM ( SELECT url
, COUNT(*) AS dupes
, MIN(datetime) AS earliest
FROM bookmarks
GROUP
BY url ) AS m
INNER
JOIN bookmarks
ON bookmarks.url = m.url
AND bookmarks.datetime = m.earliest
[COLOR="red"]LEFT OUTER
JOIN ( SELECT bookmark_id
, GROUP_CONCAT(tag) AS tags
FROM tags
GROUP
BY bookmark_id ) AS t
ON t.bookmark_id = bookmarks.id[/COLOR]
[COLOR="blue"]LEFT OUTER
JOIN ( SELECT bookmark_id
, GROUP_CONCAT(user_id) AS users
FROM links
WHERE status = 'public'
GROUP
BY bookmark_id ) AS l
ON l.bookmark_id = bookmarks.id[/COLOR]
ORDER
BY bookmarks.datetime DESC LIMIT 0, 9
Just so I know what you’re asking, you want me to make the bookmark_id and tag columns in the tags table primary keys, and similarly, the bookmark_id and user_id columns in the links table primary keys, too?
I tried bookmark_id and tag in the tags table, but got an error:
#1170 - BLOB/TEXT column ‘tag’ used in key specification without a key length
Incidentally, tag is already an index of type FULLTEXT; used in the search function of the website.
BTW — I bought your book “Simply SQL”. I thought it was the least I could do, given all of the wonderful help you’ve provided me with, not just here, but at least two or three times previously.
i’m not sure what kind of tags you anticipate having, but i will guess that the longest one is not going to reach 100 characters, never mind the 65K that a TEXT column reserves
and fulltext indexing of comma-delimited strings is definitely wrong
you need to redesign it so that each tag on a particular bookmark gets its own row, so that the “tag” column contains only one word (or phrase, if you allow phrases as tags), and a bookmark has as many rows in the tags table as there are tags on that bookmark
LEFT OUTER
JOIN ( SELECT bookmark_id
, GROUP_CONCAT(tag) AS tags
FROM tags
GROUP
BY bookmark_id ) AS t
ON t.bookmark_id = bookmarks.id
that join was predicated on the assumption that each tag is in a separate row, and the grouping in the subquery produces the comma-delimited list as a result column
if you had like all the tags for a bookmark in a TEXT column, there would’ve been no need to do any grouping of rows
You’ve misunderstood me — each tag is a completely separate entry in the tags table.
I’m no SQL expert, but I’m no idiot, either!
So what I’m saying is (and I should have said this first time around), the user enters their tags as a comma-delimited “flat” list, in a text field. Then, the Under Cloud adds each tag as a unique entry, with the ID of the bookmark they belong to.
my apologies, i did not know about this step --[indent]“Then, the Under Cloud adds each tag as a unique entry, with the ID of the bookmark they belong to.”[/indent]