Другие языки программирования и технологии

Помогите создать запрос на SQL

Есть к примеру в базе данных таблица Книги. В ней есть поля ИД, Название, Автор, Год издания, Аннотация, Цена. ИД ключевое поле. Нужно вывести данные из этой таблицы отсортировав по автору и с распределением по годам. Год издания предопределен (с 2005 до 2009) и не может иметь другие значения То есть конечная таблица должна выглядеть так: Автор (не повторяющееся поле) |Количество книг за 2005г|Количество книг за 2006г|Количество книг за 2007г|Количество книг за 2008г|Количество книг за 2009г| Ни из каких других таблиц эти данные не достать Надо обойтись минимумом запросов. Оптимально всего один запрос Не повторяющееся поле значит, для каждого автора нужно вывести один такой результат Рядом с полями количество книг могут быть и другие поля (например Общая цена книг автора за каждый год)
Elcin Memmedov
Elcin Memmedov
4 415
select автор,
sum(case [год издания] when 2005 then 1 else 0 end) as [2005],
sum(case [год издания] when 2006 then 1 else 0 end) as [2006],
sum(case [год издания] when 2007 then 1 else 0 end) as [2007],
sum(case [год издания] when 2008 then 1 else 0 end) as [2008],
sum(case [год издания] when 2009 then 1 else 0 end) as [2009]
from книги
group by автор
Максим Поохоло
Максим Поохоло
7 152
Лучший ответ
Elcin Memmedov В итоге запрос получается примерно такой:
select [автор],
sum(case when [год издания] = 2005 and [Издательство] = 'BestSeller' then 1 else 0 end) as bcbs05,
sum(case when [год издания] = 2005 and [Издательство] = 'Another' then 1 else 0 end) as bcan05
from [Книги]
group by [Автор]
Можно ли здесь сразу суммировать bcbs05 и bcan05 или придется добавлять новую строку
sum(case when [год издания] = 2005 then 1 else 0 end) as sumbc05
?
Бессмысленно рассуждать об "оптимальности" без конкретизации целевой СУБД
Elcin Memmedov Под оптимальностью имеется ввиду именно количество запросов, а не быстродействие
А целевая СУБД MySQL
Например так:

select a.Автор, a5.колво, а6.колво, а7.колво, а8.колво, а9.колво from (select distinct Автор from Книги) а, (select COUNT(*) колво from Книги b where b.Автор = а. Автор, b.Год=2005) а5, (select COUNT(*) колво from Книги b where b.Автор = а. Автор, b.Год=2006) а6, (select COUNT(*) колво from Книги b where b.Автор = а. Автор, b.Год=2007) а7, (select COUNT(*) колво from Книги b where b.Автор = а. Автор, b.Год=2008) а8, (select COUNT(*) колво from Книги b where b.Автор = а. Автор, b.Год=2009) а9 ORDER BY а. Автор

Если бы распределение по годам не надо было на одной строке, можно было бы сделать через GROUP BY.
Сергей Штер
Сергей Штер
26 653
Elcin Memmedov Надо именно на одной строке.
То есть по-любому придется для каждого года запрашивать отдельным оператором select? А как быть, если таблиц несколько?
Например В таблице Авторы хранится вся информация об авторе, а Книги.Автор ссылается на Автор.ИД. Причем есть таблица Город, в которых хранится данные о месте жительства автора
ИД | Название_Города | Краткое_Описание
И может потребоваться вывести вышеуказанные данные для определенного города. В таблице Авторы есть поле ИД_Города
вот вариант. Текста больше, зато можно вывести все, что нужно

SELECT автор, b.cnt as "2005",c.cnt as "2006",d.cnt as "2007" FROM (
select автор, count(*) as cnt from книги group by автор) as a left join
(select автор, count(*) as cnt from книги where [год издания] =2005 group by книги ) as b
on a.авторr=b.автор left join
(select autor,count(*) as cnt from книги where [год издания] =2006 group byкниги ) as c
on a.автор=c.автор left join
(select autor,count(*) as cnt from книги where [год издания] =2007 group by книги ) as d
on a.автор =d.автор

и так далее
М Т
М Т
467