2013-12-10 2 views
0
Table A:  Table A_B:   Table B: 
id | a   a_id | b_id  id | b 
------   -----------  ------ 
1 | w   1 | 1   1 | s 
2 | x   1 | 2   2 | t 
3 | y   2 | 4   3 | u 
4 | z   4 | 4   4 | v 

Теперь я хотел бы иметь все записи из таблицы А ГДЕ B.id = 1 И B.id = 2.SQL/Criteria Query СОДЕРЖИТ ВСЕ?

На данный момент у меня в следующий код:

SELECT * 
FROM A a 
JOIN A_B ab ON a.id = ab.a_id 
JOIN B b ON ab.b_id = b.id 

И здесь я застрял. WHERE b.id IN (...) дает мне все записи из таблицы А ГДЕ b.id = 1 OR b.id = 2 конечно, и WHERE b.id = 1 AND b.id = 2 не дает никаких результатов ...

Единственное возможное решение я нашел с помощью INTERSECT:

SELECT * 
FROM A a 
JOIN A_B ab ON a.id = ab.a_id 
JOIN B b ON ab.b_id = b.id 
WHERE b.id = 1 

INTERSECT 

SELECT * 
FROM A a 
JOIN A_B ab ON a.id = ab.a_id 
JOIN B b ON ab.b_id = b.id 
WHERE b.id = 2 

Но я могу иметь бесконечное количество b.ids. Так что этот запрос станет очень медленным ...

Нет ли что-то вроде IN, который ведет себя так, как я хочу? И это должно быть выполнено с использованием критерия Критерии:

Join<A, B> aB = root.join(A_.bs); // as this is a @ManyToMany relationship 
... 

Но я также был бы доволен чистым SQL-решением.

+0

Я не уверен, что правильно понял вопрос, но я думаю, что это случай для левого присоединения http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins .html –

+0

Ваш пример будет более ясным, если вы измените запись в A_B с 2,4 до 2,2. Затем укажите, что запись 2 в таблице A не должна возвращаться, несмотря на то, что она соответствует одному значению (поскольку оно не соответствует другому значению). – mdahlman

ответ

1

Протестировано на MySQL:

select TableA.id, count(*) 
from tableA 
join tableA_B on TableA.id=TableA_B.a_id 
where b_id =1 or b_id=2 
group by tableA.id 
having count(*)=2 

SQL Fiddle here.

+0

Отлично. Это работает! –

+1

Это зависит от подсчета ...поэтому он будет возвращать слишком много записей, если, например, A_B содержит запись 2,2 дважды. – mdahlman

0

Я должен признать, что я на самом деле не следуют вопросы и проблемы, но вы говорите, что это не работает:

SELECT * 
FROM B b 
LEFT JOIN A_B ab ON b.id = ab.b_id 
LEFT JOIN A a ON ab.a_id = a.id 
WHERE b.id IN (1,2) 
+0

Прочтите еще раз. Я нашел решение, используя INTERSECT. Но ваш запрос просто дает мне результаты из таблицы A, где b.id = 1 ИЛИ b.id = 2. Но мне нужны все записи из таблицы A, где b.id = 1 AND b.id = 2. –

0

Как я понимаю, это многие-ко-многим и вы хотите отфильтровать данные на основе идентификатора в таблице B.

Во-первых, ваш первый запрос кажется мне удобным; Я хотел бы написать это следующим образом для ясности:

select 
    a.id, a.a, b.id, b.b 
from 
    A as a 
    inner join A_B as ab on a.id = ab.a_id 
    inner join B as b on ab.b_id = b.id; 

Теперь, если вы хотите, чтобы все записи, для которых b.id = 1илиb.id = 2, это должно работать:

select 
    a.id, a.a, b.id, b.b 
from 
    A as a 
    inner join A_B as ab on a.id = ab.a_id 
    inner join B as b on ab.b_id = b.id 
where 
    b.id in (1,2); 

Проверить это SQLFiddle example

Надеюсь, это поможет

+0

Эй, спасибо. Я должен был написать скрипт SQL ... Я изменил ваш: http://sqlfiddle.com/#!2/6628f/1 (Изменены записи в таблице A_B). Результат должен теперь содержать только a.id = 1, потому что это единственная запись, которая соответствует b.id = 1 AND b.id = 2 –

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