Нужна помощь с условным оператором SELECT

У меня есть хранимая процедура с оператором выбора, например:

SELECT author_ID,
       author_name,
       author_bio
FROM   Authors
WHERE author_ID in (SELECT author_ID from Books)

Это ограничивает результаты авторами, у которых есть книжные записи. Это таблица книг:

Books:
book_ID INT,
author_ID INT,
book_title NVARCHAR,
featured_book BIT

Что я хочу сделать, так это условно выбрать идентификатор рекомендуемой книги каждым автором как часть оператора select выше, и если ни одна из книг для данного автора не представлена, выберите идентификатор первой (первой) книги с помощью автор с книжного стола. Как мне подойти к этому?


person Ethan    schedule 29.04.2010    source источник
comment
Что вы имеете в виду под первой книгой? Заказал чем? Вы имеете в виду просто принести любую книгу?   -  person Mark Byers    schedule 29.04.2010
comment
Да, реально, любую книгу этого автора. Я имел в виду топ 1, упорядоченный по book_ID.   -  person Ethan    schedule 29.04.2010


Ответы (3)


Вы можете использовать подзапрос, который упорядочивает данные и использует верхний оператор...

Что-то вроде,

SELECT  author_ID, 
         author_name, 
         author_bio
         , (Select top 1 Book_ID from Books where Authors.Author_ID=Books.Author_ID order by Featured_book desc)
 FROM    Authors 
 WHERE author_ID in (SELECT author_ID from Books) 
person KSimons    schedule 29.04.2010

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

DECLARE @Authors table (author_ID INT NOT NULL, author_name VARCHAR(100) NOT NULL, author_bio VARCHAR(100) NOT NULL)
INSERT INTO @Authors VALUES (1, 'Author1', 'Bio1')
INSERT INTO @Authors VALUES (2, 'Author2', 'Bio2')
INSERT INTO @Authors VALUES (3, 'Author3', 'Bio3')

DECLARE @Books table (book_ID INT NOT NULL, author_ID INT NOT NULL, book_title VARCHAR(100) NOT NULL, featured_book INT NOT NULL)
INSERT INTO @Books VALUES (1, 2, 'Book1', 0)
INSERT INTO @Books VALUES (2, 2, 'Book2', 1)
INSERT INTO @Books VALUES (3, 3, 'Book3', 0)
INSERT INTO @Books VALUES (4, 3, 'Book4', 0)

SELECT
    dt.author_ID, dt.author_name,dt.author_bio,dt.book_title
    FROM (
          SELECT
              a.*,b.book_title,ROW_NUMBER() OVER (PARTITION by a.author_ID ORDER BY b.featured_book DESC,b.book_title) RowNumber

          FROM Authors              a
              LEFT OUTER JOIN Books b ON a.author_id = b.author_id
          ) dt
WHERE dt.RowNumber= 1

ВЫХОД:

author_ID   author_name  author_bio  book_title
----------- ------------ ----------- ----------
1           Author1      Bio1        NULL      
2           Author2      Bio2        Book2     
3           Author3      Bio3        Book3      

(3 row(s) affected)
person KM.    schedule 29.04.2010
comment
Я так понимаю вопрос, авторы без книг не нужны. This limits results to authors who have book records. - person Mark Byers; 29.04.2010
comment
@ Марк Байерс, я не так прочитал вопрос. Ваш вопрос не входит в раздел вопроса «Что я хочу...». В ОП упоминается только то, что у них есть хранимая процедура... это ограничивает... и т.д. - person KM.; 29.04.2010

Отношение не имеет порядка в теории. Так что "первая книга" в идеале должна быть указана каким-то правилом агрегирования. Если вас устраивает "min(bookID)", то что-то вроде этого:

SELECT Authors.author_ID, author_name, author_bio,
  CASE max(featured_book)
  WHEN 0 THEN min(book_ID)
  END
FROM Authors INNER JOIN
     Books ON Authors.author_ID = Books.author_ID
GROUP BY Authors.author_ID, author_name, author_bio
person ony    schedule 29.04.2010