У меня есть две таблицы, как показано ниже.
PermissionAccessEntities
peID | petID
-------------------
1 | 1
2 | 4
3 | 1
4 | 2
5 | 4
6 | 4
-------------------
PermissionAccessEntityGroups
pegID | peID | gID
-----------------------------
1 | 5 | 1
2 | 5 | 2
3 | 5 | 3
4 | 6 | 2
5 | 6 | 3
-----------------------------
Теперь у меня есть запрос доктрины getOne, как показано ниже:
select pae.peID from PermissionAccessEntities pae
left join PermissionAccessEntityGroups paeg1 on pae.peID = paeg1.peID
left join PermissionAccessEntityGroups paeg2 on pae.peID = paeg2.peID
where petID = 4 and paeg1.gID = 2 and paeg2.gID = 3;
Что возвращает 5 и 6. Но я хочу получить результат с точным количеством совпадающих строк. В данном случае это 6.
Есть ли способ использовать JOIN для получения того же набора результатов, что и выше?
Помощь очень ценится.
К сожалению, данные в таблице неверны. Починил это.
Что вы подразумеваете под «точным количеством совпадающих строк»? Я не вижу разницы в результатах для peID=5 и peID=6.
@Nick есть одна дополнительная строка gID = 1 для peID = 5. Кажется, что OP хочет учитывать только те значения peID, которые имеют gID = 2 and 3 only
Итак, peID=5 имеет 3 gID=(1,2,3) и peID=6 имеет 2 gID=(2,3). Я хочу получить только peID=6, а не peID=5.
@MadhurBhaiya, ты прав.
@CoderBoy проверьте обновленный опубликованный ответ






Where в этом случае вам не поможет. Потому что вы хотите учитывать количество всех строк для дальнейшей фильтрации. Вам нужно будет использовать Group By с условной фильтрацией с помощью предложения Having.PermissionAccessEntityGroups.Count() используется для подсчета количества строк в группе. Мы также можем использовать Sum( conditional statements ) для подсчета количества строк, соответствующих условию. Условный оператор вернет 1 для совпадающих строк и 0 для несовпадающих строк.Вместо этого попробуйте следующий запрос:
SELECT pae.peID
FROM PermissionAccessEntities AS pae
LEFT JOIN PermissionAccessEntityGroups AS paeg
ON pae.peID = paeg.peID
WHERE pae.petID = 4
GROUP BY pae.peID
HAVING COUNT(*) = SUM(paeg.gID IN (2,3))
Теперь вспомните, что Count(NULL) = 0; однако COUNT(0) = COUNT(1) = 1. Итак, другой способ написать этот запрос с использованием только функции Count():
SELECT pae.peID
FROM PermissionAccessEntities AS pae
LEFT JOIN PermissionAccessEntityGroups AS paeg
ON pae.peID = paeg.peID
WHERE pae.petID = 4
GROUP BY pae.peID
HAVING COUNT(*) = COUNT(CASE WHEN paeg.gID IN (2,3) THEN 1 END)
Возвращает тот же результат, что и исходный запрос OP
@Nick нет, это не так. У тебя есть рабочий пример? OP изменил данные впоследствии
Да, у меня есть рабочий пример, и с новыми данными OPs ваш запрос дает точно такой же результат, как исходный запрос OP. Отсюда мой второй комментарий к вопросу.
@MadhurBhaiya & Nick Да, обновленный работает. Большое спасибо.
Вы можете достичь желаемого результата, сначала посмотрев записи, соответствующие (2,3), а затем проверив, соответствует ли какая-либо из них одному из других значений. Все, что не соответствует (paeg2.peID IS NULL), является точным совпадением:
SELECT DISTINCT(pae.peID)
FROM PermissionAccessEntities pae
JOIN PermissionAccessEntityGroups paeg1 ON paeg1.peID = pae.peID AND paeg1.gID IN (2,3)
LEFT JOIN PermissionAccessEntityGroups paeg2 ON paeg2.peID = pae.peID AND paeg2.gID NOT IN (2,3)
WHERE pae.petID = 4 AND paeg2.peID IS NULL
другой подход. Думаю, нужно еще и where pae.petID = 4 поставить. +1
@Nick Думал, что все работает нормально, мне интересно, как это будет работать для более чем двух строк? Например, у меня есть gID=1,2,3,4, и я хочу найти gID=1,2,3. Тогда нам нужно еще одно соединение?
@CoderBoy просто измените условия IN на IN (1,2,3) и NOT IN (1,2,3)
SELECT pae.peID FROM PermissionAccessEntities pae
INNER JOIN PermissionAccessEntityGroups paeg1 ON pae.peID=paeg1.peID
WHERE pae.petID = 4 AND paeg1.peID NOT IN (SELECT DISTINCT peID FROM
PermissionAccessEntityGroups WHERE gID NOT IN (2,3));
Спасибо за Ваш ответ. Он возвращает 6, но две записи.
Ваш запрос не возвращает никаких результатов для предоставленных вами образцов данных ...