Запрос MySQL для начинающих с ПОДСЧЕТОМ — «фильтр»

#mysql #sql

#mysql #sql

Вопрос:

Я публикую этот вопрос здесь, чтобы получить больше ясности в отношении моего запроса при изучении SQL (пример упрощен)

У меня есть следующие таблицы:

 BookTable(bookID, isbn, title) // Holds every book, not the ammuont, just the writing 

CopyTable(copyID, bookID)      // Represent a physical copy

AuthorTable(authorID, fName, lName)    // Represents an author

WriteTable(authorID, bookID)   // Represents who wrote what
  

Я хочу выбрать каждого автора (предпочтительно, например, {authordID, fname, lname} ), если у этого автора написана книга, у которой более 5 копий.

Я пытаюсь сделать что-то вроде этого:

 SELECT DISTINCT authorID, fname, lname   // My final "output table"
FROM T_Author
WHERE authorID IN 
    SELECT authorID, bookID
    FROM T_Write
    WHERE bookID IN
        SELECT bookID, COUNT(*) AS count
        FROM T_Copy
        GROUP BY bookID // This part I doubt the most
        WHERE count > 5
  

Итак, моя идея такова:

  1. Выберите каждый идентификатор книги, который появляется более 5 раз в таблице копирования
  2. Выберите каждого автора, который написал любую из этих книг, из таблицы записи
  3. Выпишите имя автора с данными из AuthorTable

Я не могу проверить это, если это действительно работает, но является ли это «правильным» способом решения этой проблемы?

Заранее спасибо за любые рекомендации.

Ответ №1:

Вы довольно близки. Попробуйте это:

 SELECT a.authorID, a.fname, a.lname   // My final "output table"
FROM T_Author a
WHERE a.authorID IN (SELECT w.authorID
                     FROM T_Write w
                     WHERE w.bookID IN (SELECT c.bookID
                                        FROM T_Copy c
                                        GROUP BY c.bookID // This part I doubt the most
                                        HAVING COUNT(*) > 5
                                       )
                    );
  

Примечания:

  • Подзапросы нуждаются в собственных круглых скобках.
  • Для IN возвращаемого значения должно точно соответствовать тому, что сравнивается. В общем, вы не можете вернуть два столбца.
  • Используется HAVING для фильтрации после агрегирования.
  • SELECT DISTINCT не требуется во внешнем запросе. Это просто добавляет накладные расходы на обработку.
  • Используйте псевдонимы таблиц и полные имена столбцов в любом запросе, который имеет более одной ссылки на таблицу.

Комментарии:

1. Спасибо, что прояснили вопрос О ТОМ, ГДЕ НАХОДИТСЯ vs. Итак, как вы говорите «после объединения», HAVING можно рассматривать как «дождитесь результата, затем примените фильтр»? Также спасибо за советы, я соответствующим образом исправлю свой код 🙂

2. @viesa . , , Если это помогает вам думать об этом таким образом, вы можете думать об этом таким образом.