我有一个使用下表设置的mysql数据库
CREATE TABLE IF NOT EXISTS Company(
name VARCHAR(25) NOT NULL,
description VARCHAR(512) NOT NULL,
PRIMARY KEY(name)
);
CREATE TABLE IF NOT EXISTS CompanyTag(
companyName VARCHAR(25) NOT NULL,
tag VARCHAR(25) NOT NULL,
PRIMARY KEY(companyName, tag)
);
导致看起来像这样的CompanyTag表
Company Tag
someCompany1 first
someCompany1 second
someCompany1 third
someCompany2 first
someCompany2 second
someCompany3 first
当搜索是“第一个第二个第三”时,只应返回someCompany1。当搜索是“第一秒”时,只应返回someCompany1和2。 当搜索“第一次”时,应该返回someCompany1,2和3。
目前,我可以通过执行以下查询来搜索包含一个或多个单词的公司
SELECT name, description, location, website, categoryName FROM Company
INNER JOIN CompanyTag ON CompanyTag.companyName = Company.name
WHERE tag REGEXP ?;
where ? is "^(.*first.*|.*second.*|.*third.*)$"
然而,正如您所期望的那样,这会产生ORing标记
的效果我可以对数据库或查询的结构做些什么来使我能够和标签相反,即。获得公司被标记为第一,第二和第三的所有结果,而不是第一,第二或第三。
编辑:也许这个问题不太清楚。它更像是一个SQL问题,因为与公司关联的每个标记都是CompanyTag表中的单独条目。因此,我不认为可以通过更改正则表达式来解决它,因为只有我的知识才能根据表中的单个条目进行评估,而不是所有条目连接在一起。
答案 0 :(得分:1)
我会因为使用正则表达式而尖叫这个问题。
如果您拥有独特的标签和公司以及独特的公司标签组合,您可以轻松搜索标签标题的公司。
OR逻辑:
SELECT c.*
FROM company c
JOIN companyTag ct ON ct.companyName = c.name
WHERE ct.tag IN (:1,:2,:3)
GROUP BY c.name;
AND逻辑:
SELECT c.*
FROM company c
JOIN companyTag ct ON ct.companyName = c.name
WHERE ct.tag IN (:1,:2,:3)
GROUP BY c.name
HAVING count(*) = 3;
<强>更新强>
我可能会更进一步,创建一个单独的tag
表格(id,title)
,其title
上有一个唯一的company
,id
name
和唯一的companyTag
并使(companyId, tagId)
多个{{1}}在两个字段中都是唯一的。
答案 1 :(得分:0)
你可以试试这个正则表达式:
^(?=.*first.*)(?=.*second.*)(?=.*third.*).*$
应该检查所有3个条件,first
和second
和third
必须出现在字符串中。这些词不必按照一定的顺序排列。
答案 2 :(得分:0)
我不确定正则表达式是最好的方法。假设您没有在字段tag
中存储多个分隔标记,只需使用in
:
SELECT c.name, c.description, c.location, c.website, c.categoryName
FROM Company c INNER JOIN
CompanyTag ct
ON ct.companyName = c.name
WHERE tag in ($first, $second, $third)
这样做的好处是where
子句可以利用索引。
假设您想要公司中的所有代码,请添加group by
和having
:
SELECT c.name, c.description, c.location, c.website, c.categoryName
FROM Company c INNER JOIN
CompanyTag ct
ON ct.companyName = c.name
WHERE tag in ($first, $second, $third)
GROUP BY c.name, c.description, c.location, c.website, c.categoryName
HAVING count(distinct tag) = 3; -- Note: "3" here depends on the number of tags
如果您更喜欢正则表达式方法,当然可以使用in
来代替where
。