大多数匹配标记的SQL查询

时间:2016-01-31 09:07:55

标签: sql tags

让我们想象一下抽象数据库,它包含附加标签的对象(与附加表的默认多对多关系)。现在,我们有一个用户,他希望找到符合他提供的最多标签的对象,并按相关性排序。例如:

Object1: TagA, TagB, TagC, TagD
Object2: TagA,       TagC, TagD
Object3: TagB,             TagD, TagE, TagF
Object4: TagA, TagB, TagC,       TagE

用户要求TagB,TagC,TagD 预期结果应如下所示:

Object1 (3 matches)
Object4 (2 matches)
Object2 (2 matches)
Object3 (1 match)

编辑:示例结构(我在SQLite中创建它,但我们可以安全地假设MSSql)

CREATE TABLE Objects(Id int not null primary key, Name text);
CREATE TABLE Tags(Id int not null primary key, Name text);
CREATE TABLE ObjectTag(Id int not null primary key, ObjectId int, TagId int);

INSERT INTO Objects(Id, Name) VALUES (1, "Object1");
INSERT INTO Objects(Id, Name) VALUES (2, "Object2");
INSERT INTO Objects(Id, Name) VALUES (3, "Object3");
INSERT INTO Objects(Id, Name) VALUES (4, "Object4");

INSERT INTO Tags(Id, Name) VALUES (1, "TagA");
INSERT INTO Tags(Id, Name) VALUES (2, "TagB");
INSERT INTO Tags(Id, Name) VALUES (3, "TagC");
INSERT INTO Tags(Id, Name) VALUES (4, "TagD");
INSERT INTO Tags(Id, Name) VALUES (5, "TagE");
INSERT INTO Tags(Id, Name) VALUES (6, "TagF");

INSERT INTO ObjectTag(Id, ObjectId, TagId) VALUES (1, 1, 1);
INSERT INTO ObjectTag(Id, ObjectId, TagId) VALUES (2, 1, 2);
INSERT INTO ObjectTag(Id, ObjectId, TagId) VALUES (3, 1, 3);
INSERT INTO ObjectTag(Id, ObjectId, TagId) VALUES (4, 1, 4);

INSERT INTO ObjectTag(Id, ObjectId, TagId) VALUES (5, 2, 1);
INSERT INTO ObjectTag(Id, ObjectId, TagId) VALUES (6, 2, 3);
INSERT INTO ObjectTag(Id, ObjectId, TagId) VALUES (7, 2, 4);

INSERT INTO ObjectTag(Id, ObjectId, TagId) VALUES (8, 3, 2);
INSERT INTO ObjectTag(Id, ObjectId, TagId) VALUES (9, 3, 4);
INSERT INTO ObjectTag(Id, ObjectId, TagId) VALUES (10, 3, 5);
INSERT INTO ObjectTag(Id, ObjectId, TagId) VALUES (11, 3, 6);

INSERT INTO ObjectTag(Id, ObjectId, TagId) VALUES (12, 4, 1);
INSERT INTO ObjectTag(Id, ObjectId, TagId) VALUES (13, 4, 2);
INSERT INTO ObjectTag(Id, ObjectId, TagId) VALUES (14, 4, 3);
INSERT INTO ObjectTag(Id, ObjectId, TagId) VALUES (15, 4, 5);

预期结果(查询“TagB,TagC,TagD”):

ObjectName | MatchCount
-----------+-----------
Object1    | 3
Object4    | 2
Object2    | 2
Object3    | 1

2 个答案:

答案 0 :(得分:0)

不确定您的表格结构,但是从您的帖子看起来您可以使用GROUP BY来实现此目标

select object, count(tag) as tagcount
from tags
where tag in ('TagB', 'TagC', 'TagD')
group by object;

答案 1 :(得分:0)

这是一个答案:

SELECT t1.name, COUNT(t1.tag) as count FROM
    (SELECT o.Name as name, 
        1 as tag 
     FROM Objects AS o,
        ObjectTag AS ot 
     WHERE o.Id = ot.ObjectId 
         AND ot.TagId IN (2,3,4)) AS t1
     GROUP BY t1.name
     ORDER BY count DESC