SQL查询 - 标记系统,分隔字符串+唯一值

时间:2013-01-29 14:38:14

标签: mysql sql

我正在为一个在MySQL DB中存储项目标签的客户端工作(我知道,我知道 - 不理想):

coats_and_jackets-Woven_Jacket-brand:Hobbs;
coats_and_jackets-Woven_Jacket-color:Black;
coats_and_jackets-Woven_Jacket-style:Boucle;
coats_and_jackets-Woven_Jacket-pattern:Plain;
dresses-Pinafore-brand:COS;
dresses-Pinafore-color:Blue _ Navy;
dresses-Pinafore-style:Wool;
dresses-Pinafore-pattern:Plain;
shoes-Ankle_Boot-brand:Topshop;
shoes-Ankle_Boot-color:Black;
shoes-Ankle_Boot-style:Leather;
shoes-Ankle_Boot-pattern:Plain;
bags-Tote-brand:Mulberry;
bags-Tote-color:Brown _ Tan;
bags-Tote-style:Leather;
bags-Tote-pattern:Plain;
shoes-Ballet_shoes-brand:Chanel;
shoes-Ballet_shoes-color:Black;
shoes-Ballet_shoes-style:Leather;
shoes-Ballet_shoes-pattern:Plain;
accessories-Scarf-brand:Zara;
accessories-Scarf-color:Brown _ Tan;
accessories-Scarf-style:Wool;
accessories-Scarf-pattern:Checked;

每个标签分为4个部分,如:category-type-brand,category-type-color,category-type-style,category-type-pattern

并非所有标签的4个部分都是必需的,可以从DB中省略。

我的任务是找出一个项目有多少个标签,所以在这个例子中使用了6个标签,每个标签都有4个部分。

我到目前为止的查询计算了所有标记部分,在此示例中为24,但我不能假设每个标记都将存储所有4个部分。所以不能将零件数量除以4来获得标签数量。

在此示例中,使用的6个标签如下:

高士&夹克(梭织夹克) 连衣裙(Pinafore) 鞋(踝靴) 手袋(手提包) 鞋(芭蕾舞鞋) 配饰(围巾)

现在我并不关心类别,类型或部件(品牌,颜色,款式,图案) - 我只关心获取此商品的标签总数。

此外,上面的数据示例将存储在db行中,如下所示:

+----------+-------------+----------------------------+
|  ID      | meta_key    |   meta_value               |
+----------+-------------+----------------------------+
|        1 |   tags      |  coats_and_jackets-wove... |
+----------+-------------+----------------------------+
|        2 |   item_desc |  Fashion editor            |
+----------+-------------+----------------------------+

非常感谢帮助构建此查询。

3 个答案:

答案 0 :(得分:0)

标签使用连字符作为分隔符。以下是查找给定项目使用的标记数量的方法:

select it.*, length(it.tags) - length(replace(it.tags, '-', ''))+1
from itemtags it

这会用空字符串替换连字符,并测量长度的差异。

答案 1 :(得分:0)

假设我正确理解你的要求,那么这样的事情怎么样(用CTE来表示假定的表结构)

WITH CTE1(tag) AS(
    select 'coats_and_jackets-Woven_Jacket-brand:Hobbs' union
    -- ...
    select 'accessories-Scarf-color:Brown _ Tan' union
    select 'accessories-Scarf-style:Wool' union
    select 'accessories-Scarf-pattern:Checked'
)
, CTE2(tag_prefix) AS(
    select LEFT(tag, CHARINDEX('-', tag, CHARINDEX('-', tag) + 1) - 1) from CTE1
)
select tag_prefix, COUNT(*) from CTE2 group by tag_prefix

这将为您提供......

的结果
accessories-Scarf   4
bags-Tote   4
coats_and_jackets-Woven_Jacket  4
dresses-Pinafore    4
shoes-Ankle_Boot    4
shoes-Ballet_shoes  4

...它为您提供标签前缀和使用的部件数量。从那里你可以计算单个行或总和部件的数量或你需要的任何其他......

答案 2 :(得分:0)

我刚刚意识到我的解决方案完全没有意义,因为我错过了'mysql'标签;)但我还是会把它发布在这里。希望它能给你一个关于如何继续的指针。

WITH CTE1(ID, meta_key, meta_value) AS(
    select 1, 'tags', 'coats_and_jackets-Wo...' union all
    select 2, 'item_desc', 'Fashion editor'
)
, TagsCTE AS(
    select t.ID, x.Item as tag_and_value
    from CTE1 t
    cross apply dbo.fn_SplitString(t.meta_value, ';') x
    where meta_key = 'tags' and LEN(x.Item) > 0
)
select ID, COUNT(parts_count) from (
    select ID, COUNT(*) as parts_count
    from TagsCTE
    group by ID, LEFT(tag_and_value, CHARINDEX('-', tag_and_value, CHARINDEX('-', tag_and_value) + 1) - 1)
) a group by ID

这给出了以下结果:

1   6
祝你好运。