我有一个很难的mysql问题。我有一个数据库,将关键字与案例匹配,简化:
TABLE cases (id)
TABLE keywords (id)
TABLE cases_keywords (case, keyword)
所以我可以在案例A中使用关键字Y和Z,我可以在案例B中使用关键字X和Y.这在case_keywords中给出了四行:
(A, Y)
(A, Z)
(B, X)
(B, Y)
问题:
我在我的网站上搜索,用户输入要搜索的关键字。我希望结果在找到所有关键字时显示匹配项。因此,当用户在Y和Z中键入关键字时,仅出现案例A(因为案例B没有关键字Z)。但是当用户仅将Y作为关键字时,该网站同时显示A和B(因为它们都有关键字Y)。
所以我通过PHP知道查询是动态的,最大的问题是匹配多个关键字...假设我想匹配2个关键字:Y和Z结果:案例A。
如何将其编入查询?如何在多行上匹配?
SELECT C.id FROM cases C JOIN cases_keywords CK ON CK.case = C.id WHERE CK.keyword = Y AND CK.keyword = Z
上面没有用,所以我尝试了WHERE C.case IN(),但我也被困在那里......
有人请帮帮我
答案 0 :(得分:1)
这里有2条建议。
第一个必须动态构建,效率不高,但很容易理解。
SELECT C.id
FROM cases C
JOIN cases_keywords CK1 ON CK1.case = C.id AND CK1.keyword = Y
JOIN cases_keywords CK2 ON CK2.case = C.id AND CK2.keyword = Z
效率更高,可以非动态构建: -
SELECT C.id, COUNT(CK.keyword) AS KeywordCount
FROM cases C
JOIN cases_keywords CK ON CK.case = C.id
WHERE CK.keyword IN ('Y', 'Z')
GROUP BY C.id
HAVING KeywordCount = 2
答案 1 :(得分:0)
如果您可以使用MyISAM存储引擎(或者可能是MySQL 5.6中的InnoDB),您可以使用全文索引执行以下操作(然后允许您拥有实际上是短语的关键字):
CREATE TABLE cases (id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(10) NOT NULL) Engine = MyISAM;
CREATE TABLE keywords (id INT AUTO_INCREMENT PRIMARY KEY,
word VARCHAR(10) NOT NULL) Engine = MyISAM;
ALTER TABLE keywords ADD FULLTEXT INDEX (word);
CREATE TABLE cases_keywords (`case` INT,
keyword INT,
PRIMARY KEY (`case`,keyword)) Engine = MyISAM;
INSERT INTO cases VALUES (1,'Alpha'),(2,'Beta');
INSERT INTO keywords VALUES (1,'Xylophone'),(2,'Yaks'),(3,'Zebra');
INSERT INTO cases_keywords VALUES (1,2),(1,3),(2,1),(2,2);
SELECT `cases`.name, COUNT(keywords.id) AS matches
FROM `cases`
JOIN cases_keywords
ON cases_keywords.case = `cases`.id
JOIN keywords
ON keywords.id = cases_keywords.keyword
WHERE MATCH(word) AGAINST ('(Yaks Zebra) ("Yaks Zebra") (+Yaks* +Zebra*)' IN BOOLEAN MODE)
GROUP BY `cases`.id
ORDER BY matches DESC
使用SQLFiddle:http://sqlfiddle.com/#!2/49c19/2
显然,您可以调整全文搜索以按您的需要工作,但我们使用以下BOOLEAN MODE搜索来执行以下操作(符合我们的要求):
(Yaks Zebra) -> matches any occurence in the `word` column of Yak or Zebra
("Yaks Zebra") -> matches the whole phrase "Yaks Zebra" in the `word` column
(+Yaks* +Zebra*) -> requires both Yaks and Zebra to be in the `word` column, but
also allows extra characters after each of those words...