2013-10-19 5 views
0

У меня есть Book и Author столов. Book есть много Author s (Я знаю, что это должно быть много-ко-многим, это просто ради этого примера).Выбрать книги с указанными авторами

Как выбрать все книги, которые были написаны авторами: X и по Y в одном запросе sql?

EDIT

Количество авторов может быть переменной - 3, 5 или более авторов.

Я не могу понять это сейчас (я попытался сделать JOIN s и подзапросы).

SELECT * FROM book ...?

+2

Пожалуйста, покажите нам схему базы данных. –

+0

Кроме того, какую базу данных вы используете? Oracle? DB2? –

+0

Я отредактировал ваш заголовок. Пожалуйста, смотрите: «Если вопросы включают« теги »в их названиях?] (Http://meta.stackexchange.com/questions/19190/), где консенсус« нет, они не должны ». –

ответ

3

Попробуйте это:

SELECT 
    B.Name 
FROM Books B 
    JOIN Authors A 
    ON B.AuthorID = A.ID 
WHERE A.Name IN ('X', 'Y') 
GROUP BY B.Name 
HAVING COUNT(DISTINCT A.ID) = 2 
+0

Блестящий! Оно работало завораживающе! – Xeon

+0

Вы можете опустить 'DISTINCT', это просто нужно, если у вас есть повторяющиеся записи. –

0

выбрать * из книги где автор = ....?

Мне было трудно понять вашу структуру, но это кажется лучшим способом?

Надеется, что это помогает

1

Вы можете просто дважды присоединиться к таблице авторов.

SELECT Book.* from Book 
    JOIN Author author1 
     ON author1.book_id = Book.id AND author1.author_name = 'Some Name' 
    JOIN Author author2 
     ON author2.book_id = Book.id AND author1.author_name = 'Some Other Name' 
GROUP BY Book.id 

стыки гарантируют, что только книги с обоими авторами возвращаются, и GROUP BY просто делает результирующий набор содержит только уникальные записи.

Стоит отметить, кстати, что этот запрос вернет книги, в которых не менее указаны обоими авторами. Например, если вы хотите книги только Смитом и Джонсом, а не Смитом, Джонсом и Мартином, этот запрос этого не сделает. Этот запрос вернет книги, которые имеют не менее Смит и Джонс.

+0

Так что, если бы мне пришлось создавать запрос у многих авторов (3, 5 или более), я должен был добавить новое предложение 'JOIN ON' ...? – Xeon

+0

@Xeon Это будет работать, но хм, это не будет очень масштабируемо, если RDBMS не оптимизирует его. Позвольте мне подумать минутку. – Corbin

+0

@ В настоящий момент я не могу придумать относительно приятный способ масштабирования JOINs, подобных этому, на произвольный уровень.У меня возникло бы желание пойти с подходом Гамлета Акопяна в этой ситуации (выполнение его подхода будет очень быстро ухудшаться, если число книг велико: /). Я сейчас очень заинтригован этим, поэтому, когда у меня появится шанс, я немного займусь этим. – Corbin

0

Я предполагаю, что ваша таблица авторов имеет идентификатор книги (так как это дало бы много авторов одной книге).

SELECT * from Books Where ID IN 
(SELECT BookID from Author A 
JOIN Author B on A.BookID = B.BookID and A.ID <> B.ID 
WHERE A.ID IN ('X', 'Y') AND B.ID IN ('X','Y')) 

EDIT: Ответ Гамлета намного лучше (масштабируемый).

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