выбор идентификатора, который удовлетворяет нескольким пунктам - PullRequest
5 голосов
/ 07 февраля 2012

Трудно правильно ввести, но я использую MySQL, и мне нужно выбрать один идентификатор, назовем его parent_id, который должен соответствовать значениям child_id в нескольких строках.

Например:

   +-----------+----------+
   | parent_id | child_id |
   +-----------+----------+
   |     1     |    10    |
   +-----------+----------+
   |     2     |    11    |
   +-----------+----------+
   |     2     |    12    |
   +-----------+----------+
   |     3     |    13    |
   +-----------+----------+
   |     4     |    11    |
   +-----------+----------+
   |     5     |    12    |
   +-----------+----------+

Теперь, если я передаю параметры child_id 11 и 12, мне нужно вернуть parent_id 2, но если я передаю 10 и 11, мне ничего не нужно возвращать.Кроме того, если я прохожу 11, я должен получить 4. И если я прохожу 13, я должен получить обратно 3.

Как мне поступить?Я попытался подсчитать parent_id и использовать условие HAVING, также используя предложение GROUP BY, но все, что я пробую, не отвечает всем моим требованиям.

EDIT:

Пример Fiddle: http://sqlfiddle.com/#!2/abbc4/5

РЕДАКТИРОВАТЬ2:

Ожидаемые результаты:

Переданные параметры: 11, 12 Полученный результат: 2

Переданные параметры: 11 Полученный результат: 4

Переданные параметры: 13 Полученный результат: 3

Переданные параметры: 12, 13 Полученный результат NULL

EDIT3:

Обновлена ​​спецификация.Смотрите также здесь: http://sqlfiddle.com/#!2/2f750/1

Ответы [ 3 ]

2 голосов
/ 07 февраля 2012

Следующее утверждение делает то, что вы хотите. Хотя я не уверен в его эффективности ...

select t.parent_id, t.cnt from
(
    select parent_id, count(*) cnt
    from t 
    WHERE child_id IN (12, 11)
    GROUP BY parent_id
) t
inner join
(
    select parent_id, count(*) cnt
    from t group by parent_id
) s
on t.parent_id = s.parent_id
and t.cnt = s.cnt -- Check that the parent has exactly as many children as
                  -- passed in - and not more. Prevents matching if only part
                  -- of the children of a parent were specified.
and t.cnt = 2 -- Check that all passed in children produced a match on the same
              -- parent. Prevents matching of parents that match only a subset
              -- of the specified children

Заменить 2 числом указанных детей в списке IN.

1 голос
/ 07 февраля 2012

Вы также можете использовать эту более компактную версию

select case
         when min(t.parent_id) = max(t.parent_id) -- parent_ids are the same?
              -- and all children share the same parent?
              and count(t.parent_id) = (
                          select count(parents.parent_id)
                            from t parents
                           where parents.parent_id in
                              (select parent_id
                                 from t 
                                where child_id in (11, 12) -- <= change here
                               )) 
         then t.parent_id
         else null
       end as parent_id
  from t 
 where child_id in (11, 12); -- <= and here

Я проверил это и работает для всех ваших случаев использования

Вы можете проверить здесь http://sqlfiddle.com/#!2/abbc4/183

0 голосов
/ 07 февраля 2012

Вы должны иметь две переменные, чтобы это работало. Первый - это разделенный запятыми список ваших child_ids (child_list), а второй - количество детей (количество детей в вашем child_list), которые вы ищете (child_count).

SELECT parent_id,COUNT(*) 
FROM table 
WHERE child_id IN (<child_list>) 
GROUP BY parent_id
HAVING COUNT(*)=<child_count>

Это должно дать вам желаемые результаты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...