2012-04-17 3 views
0

У меня есть следующие пять таблиц:MySQL многие-ко-многим присоединиться Наличие и запрос не работает

company  type branch  company_type  company_branch 
-------  ---- ------  -------------  -------------- 
    c_id   t_id  b_id  c_id | t_id   c_id | b_id  
    ----   ---  ----  -----------  -------------- 
    1    1  1   1 1    1  1 
    2    2  2   1 2    1  2 
       3  3   2 1    2  1 
             2 3    2  3 

Следующие два запроса работают отлично:

SELECT DISTINCT `co`.`c_id` 
FROM (`company` co) 
JOIN `company_type` t ON `t`.`c_id` = `co`.`c_id` 
WHERE `co`.`status` = 1 
GROUP BY `co`.`c_id` 
HAVING sum(if(`t`.`t_id` in (1,2),1,0)) = 2  (---> returns 1) Correct ! 

SELECT DISTINCT `co`.`c_id` 
FROM (`company` co) 
JOIN `company_branch` b ON `b`.`c_id` = `co`.`id` 
WHERE `co`.`status` = 1 
GROUP BY `co`.`id` 
HAVING sum(if(`b`.`b_id` in (1,2),1,0)) = 2  (---> returns 1) Correct ! 

Но когда я пытаюсь объединить их как из следующего, это дает мне пустой результат:

SELECT DISTINCT `co`.`c_id` 
FROM (`company` co) 
JOIN `company_branch` b ON `b`.`c_id` = `co`.`id` 
JOIN `company_type` t ON `t`.`c_id` = `co`.`id` 
WHERE `co`.`status` = 1 
GROUP BY `co`.`id` 
HAVING sum(if(`b`.`b_id` in (1,2),1,0)) = 2 AND sum(if(`t`.`t_id` in (1,2),1,0)) = 2 

Я предполагаю, что И между двумя условиями является виновником t !! У кого-то есть ключ? или работа вокруг?

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

ответ

2

Его НАВЕРНОЕ, потому что вы получаете inadvertant декартовой присоединиться, таким образом, в результате 4 записей. Два для каждой ветви и типа. Я думаю, ваши отсчеты 4 каждый ... Для того, чтобы быть уверенным, попробуйте

SELECT `co`.`c_id`, 
     sum(if(`b`.`b_id` in (1,2),1,0)) as BranchCount, 
     sum(if(`t`.`t_id` in (1,2),1,0)) as TypeCount 
    FROM (`company` co) 
     JOIN `company_branch` b ON `b`.`c_id` = `co`.`id` 
     JOIN `company_type` t ON `t`.`c_id` = `co`.`id` 
    WHERE `co`.`status` = 1 
    GROUP BY `co`.`id` 

Чтобы исправить это, я бы скорректировать следующим образом:

select co.C_ID 
    from 
     company co 
     join company_branch b 
      on co.id = b.c_id 
      and b.b_id in (1, 2) 
     join company_type t 
      on co.id = t.c_id 
      and t.t_id in (1, 2) 
    where 
     co.status = 1 
    GROUP BY 
     co.id 
    HAVING 
      count(distinct b.b_id) = 2 
     AND count(distinct t.t_id) = 2 
+0

Отлично, исправление делает работу !! - пока :-) - много thanx @DRapp и все остальные. u ребята удивительны – owsata

0

Этот запрос должен соответствовать вашим requirement.Instead с указанием условие фильтра в вашем предложении HAVING сначала вычисляет суммы для каждого co_id и применяет условие фильтра WHERE на них, используя подзапрос. Это должно работать с надеждой.

SELECT Z.* FROM 
(
SELECT `co`.`c_id`, 
     sum(if(`b`.`b_id` in (1,2),1,0)) as BranchCount, 
     sum(if(`t`.`t_id` in (1,2),1,0)) as TypeCount 
    FROM (`company` co) 
     JOIN `company_branch` b ON `b`.`c_id` = `co`.`id` 
     JOIN `company_type` t ON `t`.`c_id` = `co`.`id` 
    WHERE `co`.`status` = 1 
    GROUP BY `co`.`id` 
) Z 
WHERE Z.BranchCount=2 AND Z.TypeCount=2; 
+0

Проблема - это декартово результат ... из которых ваши подсчеты в приведенном примере будут по-прежнему равны 4 и 4 соответственно. Сначала он присоединится к Филиалу компании для первого матча, а затем ударит по типу компании за 2 записи.Затем нажмите второе совпадение в филиале и снова нажмите тип для двух других записей. Ваш запрос вернет ложный результат, если только один тип ветви, но два типа ТИПА КОМПАНИИ, так как результат будет равен 2 каждому. – DRapp

0

Btw запрос вы выложили есть некоторые ошибки, так что я пытаюсь опубликовать правильные данные, так что если кто-то хочет попробовать, что из них можно сделать. 1-й номер: SELECT DISTINCT co. c_id ОТ (company co) JOIN company_type t ON t. c_id = co. c_id ГРУППА ПО co. c_id HAVING сумма (если (tt_id в (1,2), 1,0).) = 2 второй один:

SELECT DISTINCT `co`.`c_id` 
FROM (`company` co) 
JOIN `company_branch` b ON `b`.`c_id` = `co`.`c_id` 
GROUP BY `co`.`c_id` 
HAVING sum(if(`b`.`b_id` in (1,2),1,0)) = 2 

Я исключила столбец статуса, как я не взял, что в моей структуре таблицы ,

Теперь я не уверен, что ваша бизнес-логика, но я помещаю свой окончательный SQL, как следующее:

SELECT DISTINCT `co`.`c_id`,sum(if(`cb`.`b_id` in (1,2),1,0)) cb_sum,sum(if(`ct`.`t_id` in (1,2),1,0)) ct_sum 
FROM (`company` co) 
LEFT JOIN `company_branch` cb ON `cb`.`b_id` = `co`.`c_id` 
LEFT JOIN `company_type` ct ON `ct`.`t_id` = `co`.`c_id` 
GROUP BY `co`.`c_id` 
HAVING sum(if(`cb`.`b_id` in (1,2),1,0)) = 2 AND sum(if(`ct`.`t_id` in (1,2),1,0)) = 2 

Теперь, если вы бежите, что SQL без предложения HAVING вы должны увидеть, как показано ниже:

c_id  cb_sum  ct_sum 
1   4   4 
2   1   1 

так что, если вы измените свое состояние на «> 2» вместо «= 2» вы должны получить то, что вы хотите, но другой вариант заключается в том, что вы используете UNION, чтобы объединить ваш результирующий набор следующим образом:

SELECT DISTINCT `co`.`c_id` 
FROM (`company` co) 
JOIN `company_type` t ON `t`.`c_id` = `co`.`c_id` 
GROUP BY `co`.`c_id` 
HAVING sum(if(`t`.`t_id` in (1,2),1,0)) = 2 
UNION 
SELECT DISTINCT `co`.`c_id` 
FROM (`company` co) 
JOIN `company_branch` b ON `b`.`c_id` = `co`.`c_id` 
GROUP BY `co`.`c_id` 
HAVING sum(if(`b`.`b_id` in (1,2),1,0)) = 2 

 Смежные вопросы

  • Нет связанных вопросов^_^