Предположим, у меня есть таблица как:
ID|Word |Reference
1 |Dog |1
1 |Fish |2
1 |Sheep|3
2 |Dog |4
2 |Fish |5
3 |Sheep|6
4 |Dog |7
Я хочу выбрать все идентификаторы, которые имеют слово Dog А ТАКЖЕ Овца. Таким образом, результатом должны быть идентификаторы: 1 и 2. Я попытался использовать этот запрос:
SELECT ID FROM `Table` WHERE Word='Dog' OR Word='Fish' GROUP BY ID Having Word='Dog AND Word='Fish'
Тем не менее, это AND
в Having
предложение заставляет меня получить 0 результатов. Итак, я делаю что-то не так или есть другой способ добиться нужной мне суммы, основываясь только на запросе MySQL (для оптимизации скорости, поскольку он должен искать во многих строках с такой же настройкой, как в примере выше)
В основном проблема заключается в операторе AND для нескольких строк с одинаковым идентификатором.
ОБНОВИТЬ:
Мне нужно получить ссылку на идентификаторы, которые были найдены. Например. когда возвращаются идентификаторы 1 и 2, мне нужно знать, что идентификатор 1 имеет ссылку 1 и 2. ID 2 имеет ссылку 3 и 4. В настоящее время я использую этот запрос:
SELECT ID FROM `Test` WHERE Word in ('Dog', 'Fish') GROUP BY ID HAVING count(DISTINCT Word) = 2;
Спасибо
Вот два решения, которые возвращают правильные записи: первое в виде отдельных записей по идентификатору и ссылке, а второе — по одной записи для каждого идентификатора, а слова и ссылки — через запятую в столбцах.
Настройте таблицу и заполните строки:
DROP TABLE IF EXISTS `list1`;
CREATE table `list1` (
id int(10),
Word varchar(10),
Reference int(10)
);
INSERT INTO `list1` (`ID`, `Word`, `Reference`)
VALUES
(1, 'Dog',1),
(1 ,'Fish',2),
(1 ,'Sheep',3),
(2 ,'Dog',4),
(2 ,'Sheep',5),
(3 ,'Sheep',6),
(4 ,'Dog',7);
Возвращает одну строку для каждой комбинации ID и Word
SELECT
t.`ID`,
t.`Word`,
t.`Reference`
FROM `list1` as t
JOIN (
SELECT
t1.`ID` as `ref_id`
FROM `list1` AS t1
WHERE `Word` in ('Sheep','Dog')
GROUP BY t1.`ID`
HAVING count(DISTINCT t1.`Word`) = 2
) AS ts
ON t.`ID` = ts.`ref_id`
WHERE t.`Word` in ('Sheep','Dog')
ORDER BY t.`ID`,t.`Word`;
Результаты
ID | Word | Reference
1 | Dog | 1
1 | Sheep | 3
2 | Dog | 4
2 | Sheep | 5
Возвращает одну строку для каждого идентификатора с разделенным запятыми списком слов в одном столбце и разделенным запятыми списком ссылок в другом.
SELECT
t.`ID`,
GROUP_CONCAT(t.`Word`) AS `Words`,
GROUP_CONCAT(t.`Reference`) AS `References`
FROM `list1` as t
JOIN (
SELECT
t1.`ID` as `ref_id`
FROM `list1` AS t1
WHERE `Word` in ('Sheep','Dog')
GROUP BY t1.`ID`
HAVING count(DISTINCT t1.`Word`) = 2
) AS ts
ON t.`ID` = ts.`ref_id`
WHERE t.`Word` in ('Sheep','Dog')
GROUP BY t.`ID`
ORDER BY t.`ID`,t.`Word`;
Результаты:
ID | Words | References
1 | Dog,Sheep | 1,3
2 | Dog,Sheep | 4,5
Вам нужно присоединиться к столу по себе. Таким образом, вы можете узнать, где идентификаторы одинаковы для случаев, когда собаки и овцы перекрываются.
Попробуй это:
declare @t table (id int , Word varchar(10) )
insert into @t (ID, Word) values (1, 'Dog'),
(1 ,'Fish'),
(1 ,'Sheep'),
(2 ,'Dog'),
(2 ,'Sheep'),
(3 ,'Sheep'),
(4 ,'Dog')
select t.ID
from @t as t
join @t as t1 on t1.id = t.id
where t.word = 'Dog' and t1.word = 'Sheep'
Вот один из способов сделать это, присоединив свой стол к себе.
SELECT t1.id FROM `Table` t1
INNER JOIN `Table` t2 ON t1.id = t2.id
WHERE t1.word='Dog' AND t2.word='Sheep';
Ответ на мою проблему решается с помощью нижеследующего запроса:
SELECT ID, GROUP_CONCAT(Reference) as ReferencesGrouped FROM `Test` WHERE Word in ('Dog', 'Fish') GROUP BY ID HAVING count(DISTINCT Word) = 2;
Это вернет меня:
ID|ReferencesGrouped
1 |1,4
2 |4,5