MySQL 全文搜索 - 对同一字段进行多次搜索

MySQL Full Text Search - multiple search for the same field

我有这些 table:

|   ID   | detail_id |       detail_value       | book_id |

| ------ | --------- |------------------------- | ------- |

| 1      | 11        | Warszawa                 | 103     |

| 2      | 14        | Grażyńskiego             | 123     |

| 3      | 11        | st.Warszawa m            | 123     |

| 4      | 14        | Michała Grażyńskiego     | 222     |

| 5      | 11        | Warszawa                 | 222     |

| 6      | 14        | Katowicka                | 103     |

| 7      | 9         | 923                      | 23      |

| 8      | 12        | 432424                   | 23      |

| 9      | 14        | Przykładowa              | 23      |

| 10     | 11        | Warszawa                 | 23      |

detail_id: 14 - 这是街道名称,11 - 这是城市名称(其他不重要)。

现在,我有两个短语(用户在我的网站上写的): warszawa(detail_id:11 - 这是城市名称)和 grażyń(detail_id:14 - 这是街道名称的一部分)。

现在我想获取所有 book_id 为 123 和 222 的记录,因为这些记录包含短语 warszawa as detail_id = 11 和短语 grażyń as detail_id = 14.

这是我的 sql 请求:

SELECT * FROM `table` WHERE (detail_id = 11 AND MATCH (detail_value) AGAINST ('*warszawa*' IN BOOLEAN MODE)) AND (detail_id = 14 AND MATCH (detail_value) AGAINST ('*grażyń*' IN BOOLEAN MODE))

问题是 - 这个请求 return 没有结果。当我尝试使用此查询的一部分时:

SELECT * FROM `table` WHERE detail_id = 11 AND MATCH (detail_value) AGAINST ('*warszawa*' IN BOOLEAN MODE)

或:

SELECT * FROM `table` WHERE detail_id = 14 AND MATCH (detail_value) AGAINST ('*grażyń*' IN BOOLEAN MODE)

这很好用,但是当我想合并这些查询时,我没有得到任何结果。

您可以使用 extss,但 youtrr 查询实际上返回零行

CREATE TABLE `table` (
  `ID` INTEGER,
  `detail_id` INTEGER,
  `detail_value` VARCHAR(20),
  `book_id` INTEGER
  ,
       FULLTEXT idx (detail_value)
);

INSERT INTO `table`
  (`ID`, `detail_id`, `detail_value`, `book_id`)
VALUES
  ('1', '11', 'Warszawa', '103'),
  ('2', '14', 'Grażyńskiego', '123'),
  ('3', '11', 'st.Warszawa m', '123'),
  ('4', '14', 'Michała Grażyńskiego', '222'),
  ('5', '11', 'Warszawa', '222'),
  ('6', '14', 'Katowicka', '103'),
  ('7', '9', '923', '23'),
  ('8', '12', '432424', '23'),
  ('9', '14', 'Przykładowa', '23'),
  ('10', '11', 'Warszawa', '23');
SELECT * FROM `table` WHERE (detail_id = 11 AND MATCH (detail_value) AGAINST ('*warszawa*' IN BOOLEAN MODE)) 
AND EXISTS (SELECT 1 FROM `table` WHERE detail_id = 14 AND MATCH (detail_value) AGAINST ('*rażyń*' IN BOOLEAN MODE))
ID | detail_id | detail_value | book_id
-: | --------: | :----------- | ------:
SELECT * FROM `table` WHERE (detail_id = 11 AND MATCH (detail_value) AGAINST ('*warszawa*' IN BOOLEAN MODE)) 
ID | detail_id | detail_value  | book_id
-: | --------: | :------------ | ------:
 1 |        11 | Warszawa      |     103
 3 |        11 | st.Warszawa m |     123
 5 |        11 | Warszawa      |     222
10 |        11 | Warszawa      |      23
SELECT 1 as test FROM `table` WHERE detail_id = 14 AND MATCH (detail_value) AGAINST ('*rażyń*' IN BOOLEAN MODE)
| test |
| ---: |

db<>fiddle here

更改第二个查询

SELECT * FROM `table` WHERE (detail_id = 11 AND MATCH (detail_value) AGAINST ('*warszawa*' IN BOOLEAN MODE)) 
AND EXISTS (SELECT 1 FROM `table` WHERE detail_id = 14 AND MATCH (detail_value) AGAINST ('grażyń*' IN BOOLEAN MODE))
ID | detail_id | detail_value  | book_id
-: | --------: | :------------ | ------:
 1 |        11 | Warszawa      |     103
 3 |        11 | st.Warszawa m |     123
10 |        11 | Warszawa      |      23
SELECT * FROM `table` WHERE (detail_id = 11 AND MATCH (detail_value) AGAINST ('*warszawa*' IN BOOLEAN MODE)) 
ID | detail_id | detail_value  | book_id
-: | --------: | :------------ | ------:
 1 |        11 | Warszawa      |     103
 3 |        11 | st.Warszawa m |     123
 5 |        11 | Warszawa      |     222
10 |        11 | Warszawa      |      23
SELECT 1 as test FROM `table` WHERE detail_id = 14 AND MATCH (detail_value) AGAINST ('grażyń*' IN BOOLEAN MODE)
| test |
| ---: |
|    1 |
|    1 |

db<>fiddle here

好的,因为进一步的约束必须具有相同的 bookng _id

SELECT * FROM `table` t1 
WHERE (detail_id = 11 AND MATCH (detail_value) AGAINST ('*warszawa*' IN BOOLEAN MODE)) 
AND EXISTS (SELECT 1 
FROM `table` 
WHERE detail_id = 14 AND MATCH (detail_value) AGAINST ('grażyń*' IN BOOLEAN MODE)
AND book_id = t1.book_id)
ID | detail_id | detail_value  | book_id
-: | --------: | :------------ | ------:
 3 |        11 | st.Warszawa m |     123
 5 |        11 | Warszawa      |     222

db<>fiddle here

The problem is - this request return no results.

您写道:

SELECT * FROM `table` WHERE (detail_id = 11 AND MATCH (detail_value) AGAINST ('*warszawa*' IN BOOLEAN MODE)) AND (detail_id = 14 AND MATCH (detail_value) AGAINST ('*grażyń*' IN BOOLEAN MODE))

在最好的情况下意味着:

WHERE (detail_id = 11) AND (detail_id = 14)

如何让(detail_id = 11)(detail_id = 14)排成一行?

您必须使用连接,然后根据您的列进行过滤:

select 
street.book_id,
street.detail_value as street_name,
city.detail_value as city_name
from
(select * from `table` where detail_id = 14) as street
join (select * from `table` where detail_id = 11) as city on city.book_id=street.book_id

结果是:

book_id street_name city_name
103 Katowicka Warszawa
123 Grażyńskiego st.Warszawa m
222 Michała Grażyńskiego Warszawa
23 Przykładowa Warszawa

现在您可以轻松过滤它

test it

select 
street.book_id,
street.detail_value as street_name,
city.detail_value as city_name
from
(select * from `table` where detail_id = 14 and MATCH (detail_value ) AGAINST ('*grażyń*' IN BOOLEAN MODE)) as street
join (select * from `table` where detail_id = 11 and MATCH (detail_value ) AGAINST ('*warszawa*' IN BOOLEAN MODE) ) as city on city.book_id=street.book_id
book_id street_name city_name
123 Grażyńskiego st.Warszawa m
222 Michała Grażyńskiego Warszawa

注意:根据您 table

的大小决定