#mysql #sql
#mysql #sql
Вопрос:
У меня есть таблицы, как показано ниже:
CREATE TABLE `event` (
`id` int(11) NOT NULL,
`name` text CHARACTER SET utf8 NOT NULL,
`extra_info` text CHARACTER SET utf8,
`category` text CHARACTER SET utf8,
`date` datetime NOT NULL,
`is_deleted` int(11) NOT NULL
);
INSERT INTO `event`
(`id`, `name`, `extra_info`, `category`, `date`, `is_deleted`) VALUES
('1', 'EVENT1', 'dog', 'other','2020-08-21 12:25:48', '0'),
('2', 'EVENT2', 'cat', 'sport','2020-08-21 12:25:48', '0'),
('3', 'EVENT3', 'fruit', 'sport','2020-08-21 12:25:48', '0'),
('4', 'EVENT4', 'coffee', 'sport','2020-08-21 12:25:48', '0'),
('5', 'EVENT5', '', 'sport','2020-08-21 12:25:48', '0'),
('6', 'EVENT6', '', 'sport','2020-08-21 12:25:48', '0'),
('7', 'EVENT7', '', 'other','2020-08-21 12:25:48', '0'),
('8', 'EVENT8', '', 'sport','2020-08-21 12:25:48', '0');
CREATE TABLE `event_has_keyword` (
`event_id` int(11) NOT NULL,
`keyword_id` int(11) NOT NULL
);
INSERT INTO `event_has_keyword`
(`event_id`, `keyword_id`)
VALUES
('3', '4'),
('6','2'),
('8', '1'),
('6','6'),
('8', '2'),
('6','3'),
('1','4'),
('3', '3');
CREATE TABLE `event_keywords` (
`id` int(11) NOT NULL,
`name` text CHARACTER SET utf8 NOT NULL,
`is_deleted` int(11) NOT NULL
);
INSERT INTO `event_keywords`
(`id`, `name`, `is_deleted`)
VALUES
('1', 'labrador', '0'),
('2', 'dog', '0'),
('3', 'cat with space', '0'),
('4', 'keyword1', '0'),
('5', 'keyword2', '0'),
('6', 'keyword3', '0');
Что я пытаюсь сделать, так это найти все события, в которых КАТЕГОРИЯ, EXTRA_INFO или КЛЮЧЕВОЕ СЛОВО соответствуют заданному запросу.
SELECT E.*, K.`name` AS keywords, GROUP_CONCAT(K.`name`) AS keywords
FROM `event` E
LEFT JOIN `event_has_keyword` EK
ON E.`id` = EK.`event_id`
LEFT JOIN event_keywords K
ON EK.`keyword_id` = K.`id`
WHERE E.`is_deleted` = 0
AND FIND_IN_SET (K.`name` , 'labrador,dog,cat,cat with space,other')
OR FIND_IN_SET (E.`category` , 'labrador,dog,cat,cat with space,other')
OR FIND_IN_SET (E.`extra_info` , 'labrador,dog,cat,cat with space,other')
GROUP BY E.`id`
ORDER BY 1 ASC
Мне нужно объединить FIND_IN_SET для работы со всеми столбцами K.'name'
, E.'category'
а E.'extra_info'
не только с одним.
Поэтому, когда я ищу «лабрадор, собака, кошка с пробелом, другое», я должен найти все события, где:
K.'name'
является ли лабрадор или собака или кошка или кошка с пробелом или другое и
все события, где E.'category'
является лабрадор или собака или кошка или кошка с пробелом или другое и
все события, где E.'extra_info'
является лабрадор или собака или кошка или кошка с пробелом или другое
В следующем случае я должен получить:
---- -------- ------------ ---------- --------------------- ------------ -------------------------------
| id | name | extra_info | category | date | is_deleted | keywords |
---- -------- ------------ ---------- --------------------- ------------ -------------------------------
| 1 | EVENT1 | dog | other | 2020-08-21 12:25:48 | 0 | keyword1 |
---- -------- ------------ ---------- --------------------- ------------ -------------------------------
| 2 | EVENT2 | cat | sport | 2020-08-21 12:25:48 | 0 | |
---- -------- ------------ ---------- --------------------- ------------ -------------------------------
| 3 | EVENT3 | fruit | sport | 2020-08-21 12:25:48 | 0 | keyword1, cat with space |
---- -------- ------------ ---------- --------------------- ------------ -------------------------------
| 6 | EVENT6 | | sport | 2020-08-21 12:25:48 | 0 | dog, keyword3, cat with space |
---- -------- ------------ ---------- --------------------- ------------ -------------------------------
| 7 | EVENT7 | | other | 2020-08-21 12:25:48 | 0 | |
---- -------- ------------ ---------- --------------------- ------------ -------------------------------
| 8 | EVENT8 | | sport | 2020-08-21 12:25:48 | 0 | labrador, dog |
---- -------- ------------ ---------- --------------------- ------------ -------------------------------
но я все еще получаю только:
---- -------- ------------ ---------- --------------------- ------------ -------------------------------
| id | name | extra_info | category | date | is_deleted | keywords |
---- -------- ------------ ---------- --------------------- ------------ -------------------------------
| 3 | EVENT3 | fruit | sport | 2020-08-21 12:25:48 | 0 | keyword1, cat with space |
---- -------- ------------ ---------- --------------------- ------------ -------------------------------
| 6 | EVENT6 | | sport | 2020-08-21 12:25:48 | 0 | dog, keyword3, cat with space |
---- -------- ------------ ---------- --------------------- ------------ -------------------------------
| 8 | EVENT8 | | sport | 2020-08-21 12:25:48 | 0 | labrador, dog |
---- -------- ------------ ---------- --------------------- ------------ -------------------------------
таким образом, он выполняет поиск только по ключевым словам K.'name'
и игнорирует E.'category'
и E.'extra_info'
при попытке добавить скобки:
WHERE E.`is_deleted` = 0
AND (FIND_IN_SET (K.`name` , 'labrador,dog,cat,cat with space,other')
OR FIND_IN_SET (E.`category` , 'labrador,cat,dog,cat with space,other')
OR FIND_IN_SET (E.`extra_info` , 'labrador,cat,dog,cat with space,other'))
возвращает значение null
Спасибо!
Комментарии:
1. У вас есть какая-либо ошибка или несоответствие результата? пожалуйста, добавьте ожидаемый результат
2. Спасибо! отредактированный вопрос
3. Используйте IN вместо find_in_set
4. Я не могу получить результаты из вашего текущего запроса с помощью этого примера данных. Можете ли вы создать скрипку: dbfiddle.uk/?rdbms=mysql_5.7 с вашими образцами данных и результатами, которые возвращает ваш текущий запрос?
5. Две проблемы: оператор Insert для оператора
event
has;
in between, поэтому некоторые записи не вставлены, и, во-вторых, почему вы ожидаете, что идентификатор события 2 в результирующем наборе?
Ответ №1:
cat
и cat with space
не являются одной и той же строкой. Вы должны добавить cat
отдельно, чтобы найти в наборе. Здесь sqlfiddle работает в соответствии с вашим желанием.
SELECT E.*, K.`name` AS keywords, GROUP_CONCAT(K.`name`) AS keywords
FROM `event` E
LEFT JOIN `event_has_keyword` EK
ON E.`id` = EK.`event_id`
LEFT JOIN event_keywords K
ON EK.`keyword_id` = K.`id`
WHERE E.`is_deleted` = 0
AND (FIND_IN_SET (K.`name` , 'labrador,dog,cat with space,other')
OR FIND_IN_SET (E.`category` , 'labrador,dog,cat with space,other')
OR FIND_IN_SET (E.`extra_info` , 'labrador,dog,cat,cat with space,other'))
GROUP BY E.`id`
ORDER BY 1 ASC
Комментарии:
1. Спасибо!
cat
иcat with space
была ли моя ошибка допущена при создании этого вопроса. В вашем sqlfiddle это выглядит совершенно нормально, но (что странно) на моей стороне он ищет только через K.’name’ и игнорирует E.’category’ и E.’extra_info’. Я только что заметил, что если я оставлю толькоAND FIND_IN_SET (E.
extra_info,: key_words)
, это ничего не вернет…2. перетасуйте порядок FIND_IN_SET и повторите попытку. возникает ли проблема каждый раз??
3. Спасибо! Я только что заметил, что если я оставлю только
AND FIND_IN_SET (E.extra_info,: key_words)
, это ничего не вернет…4. Добро пожаловать. Вот почему я сказал, что
cat
иcat with space
являются отдельными5. Я проверил в sqlfiddle. Он не пустой