SQL-запрос для извлечения информации тега из одной таблицы - PullRequest
1 голос
/ 07 марта 2011

У меня есть таблица (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), smarty(1), jquery(1), doctrine(1)

Помните, что символы не всегда разделены пробелом, некоторые символы разделены запятой (,)

тогда мне нужен запрос для извлечения всех записей с определенными тегами. который я думаю, я могу использовать что-то подобное, пока есть лучшее решение для этого.

Select * from snippets where tag like "%ZEND%"

ищите оптимизированные решения, пожалуйста.

Ответы [ 3 ]

1 голос
/ 07 марта 2011

Задумывались ли вы о разделении исходного кода и тегов на отдельные таблицы?

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 голос
/ 07 марта 2011

создайте три таблицы!

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%'
0 голосов
/ 07 марта 2011

Сначала необходимо заменить все символы, такие как ',' пробел и т. Д., На фиксированный символ "разделитель", такой как "#" Вы можете использовать временную таблицу.

Затем вам нужно создать функцию, которая перебирает поля, ищет и подсчитывает отдельные теги.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...