Mysql 从单个表获取标记信息的sql查询
我有一个Mysql表,其中有不同的代码片段,在一个冒号中有标签Mysql 从单个表获取标记信息的sql查询,mysql,sql,Mysql,Sql,我有一个Mysql表,其中有不同的代码片段,在一个冒号中有标签 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), s
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)
记住标记并不总是用空格表示,有些标记用逗号分隔
然后我需要一个查询来获取具有特定标记的所有记录。我想我可以使用类似的东西,直到有更好的解决方案
Select * from snippets where tag like "%ZEND%"
寻找优化的解决方案,请 首先,您必须将所有字符(如“,”空格等)替换为固定分隔符(如)。你可以用一张临时桌子
然后,您必须创建一个函数,该函数在字段上循环并搜索和统计单个标记。您是否考虑过将源代码和标记分离到单独的表中
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
这将触发触发器并填充新表,并在不影响现有代码的情况下使一切变得更容易。当然,您需要将所有已知的测力仪更换为一个测力仪,以使其正常工作。
任何添加或修改的新记录都将自动触发。创建三个表
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%'
当标记为否定时,是否有任何评论。。。。问题出了什么问题?有sql解决方案吗?我知道在一张桌子上储存不是最好的方式。但这正是先驱者所做的。所以我必须处理这个问题。这可能是规范化表的最好方法。但是我不想改变表的结构,因为它可能会使其他模块不稳定。这是唯一的办法吗?或者我可以处理一些sql查询。这是很好的规范化。sql中是否有一种方法可以使用现有的表结构,因为每件事都做得很糟糕。我不想花太多时间来改变整个结构。是否有任何sql查询可以使用现有结构执行此工作。谢谢你的帮助。我真的很感激。如果性能不重要,您可以使用正则表达式:从标记中选择*,其中name REGEXP^ |[,]+zend$|[,]+只获取zend标记,而zendalicous之类的标记是不匹配的!但是布拉布拉,赞德,或者布拉布拉,赞德,布拉布拉会匹配的。