我有一个表(Mysql),其中包含带有coloumns中标签的不同片段
table snippets
---------------
Id title source tag
1 "title" "srouce code" "Zend, Smarty"
2 "title2" "srouce code2" "Zend jquery"
3 "title3" "srouce code3" "doctrine"
我想做一个select语句,这样我就可以在我的网站上构建标签云。
Zend(2), smarty(1), jquery(1), doctrine(1)
记住,tages并不总是按空间分配,有些tages用逗号分隔(,)
然后我需要一个查询来获取具有特定tages的所有记录。我认为我可以使用类似的东西,直到有更好的解决方案。
Select * from snippets where tag like "%ZEND%"
请寻找优化的解决方案。
答案 0 :(得分:1)
您是否考虑过将源代码和标签分成不同的表?
Source Table
ID, Title, Source
1 "t1" "sc"
2 "t2" "sc"
3 "t3" "sc"
Tag Table
ID, Tag
1 "Zend"
2 "Smarty"
3 "jquery"
4 "doctrine"
SourceTagLink Table
SourceID, TagID
1 1
1 2
2 1
2 3
3 4
通过这种方式,您可以选择或添加一个唯一的标记列表。 你不会做任何字符串解析,所以你的选择会更快。类似于您在此网站上为帖子分配标记的方式。
修改强>
这是一个函数,我用来将多值字符串转换为一个表,它编写的单个列是MSSQL但你应该能够将它转换为mySQL
CREATE FUNCTION [dbo].[ParseString](@String NVARCHAR(4000), @Delimiter CHAR(1)=',')
RETURNS @Result TABLE(tokens NVARCHAR(4000))
AS
BEGIN
-- We will be seearching for the index of each occurrence of the given
-- delimiter in the string provided, and will be extracting the characters
-- between them as tokens.
DECLARE @delimiterIndex INT
DECLARE @token NVARCHAR(4000)
-- Try to find the first delimiter, and continue until no more can be found.
SET @delimiterIndex = CHARINDEX(@Delimiter, @String)
WHILE (@delimiterIndex > 0)
BEGIN
-- We have found a delimiter, so extract the text to the left of it
-- as a token, and insert it into the resulting table.
SET @token = LEFT(@String, @delimiterIndex-1)
INSERT INTO @Result(tokens) VALUES (LTRIM(RTRIM(@token)))
-- Chop the extracted token and this delimiter from our search string,
-- and look for the next delimiter.
SET @String = RIGHT(@String, LEN(@String)-@delimiterIndex)
SET @delimiterIndex = CHARINDEX(@Delimiter, @String)
END
-- We have no more delimiters, so place the remainder of the string
-- into the result as our last token.
SET @token = @String
INSERT INTO @Result(tokens) VALUES (LTRIM(RTRIM(@token)))
RETURN
END
基本上你称之为
ParseString('this be a test', ' ')
it will return a single column table
this
be
a
test
ParseString('this:be a test', ':')
returns
this
be a test
您可以在更新触发器中添加对函数的调用以填充新表,以帮助您更轻松地进行选择。构建触发器后,只需执行以下
之类的简单更新Update yourTable
Set Title = Title
填充触发器并填充新表,使您更容易,而不会影响现有代码。当然,你需要用一个替换所有已知的分界符才能工作。
添加或修改的任何新记录都会自动触发触发器。
答案 1 :(得分:1)
创建三个表!
table snippets
id | title | source_code
1 "title" "srouce code"
2 "title2" "srouce code2"
3 "title3" "srouce code3"
table tags
id | tag
1 "zend"
2 "smarty"
3 "doctrine"
4 "jquery"
table snippets_tags
id | snippet_id | tag_id
1 1 1
2 1 2
3 2 1
4 2 4
5 3 3
提示小写您的代码,因为“Zend”和“zend”是相同的
现在您的标签云查询应该是
SELECT tags.name, COUNT(snippets_tags.id) AS snippet_count
FROM tags LEFT JOIN snippets_tags ON snippets_tags.tag_id = tags.id
GROUP BY tags.id
给你一个像
的结果name | snippet_count
zend 2
smarty 1
doctrine 1
jquery 1
选择属于某个代码的所有代码段:
SELECT snippets.* FROM snippets, tags, snippets_tags
WHERE
snippets_tags.snippets_id = snippet.id AND
snippets_tags.tag_id = tags.id AND
tags.name LIKE '%zend%'
答案 2 :(得分:0)
首先,你必须用'#'等固定的“分隔符”字符替换所有字符,如','space等。你可以使用临时表。
然后你必须创建一个循环遍历字段并搜索和计算单个标记的函数。