#sql #function #tsql #stored-procedures #sql-server-2012
#sql #функция #tsql #хранимые процедуры #sql-сервер-2012
Вопрос:
Я работаю на SQL Server 2012 и сталкиваюсь с проблемой: ошибка count для книг, связанных с автором. Почему значение count для книг, связанных с автором, неверно для автора Ahmed?
Когда подсчитывается автор Ахмед, я получаю неверный результат, хотя у него есть связанные записи в таблице books как 3 и bookupdate 3, тогда все будет 6.
Как это решить, пожалуйста?
create table #books
(
BookId int,
BookName nvarchar(200),
AuthorId int
)
create table #booksUpdate
(
BookId int,
BookName nvarchar(200),
AuthorId int
)
insert into #booksUpdate
values (119, 'matlab', 1), (120, '3dmax', 1), (121, 'c', 1)
create table #Authors
(
AuthorId int,
AuthorName nvarchar(200)
)
insert into #Authors
values (1, 'Ahmed'), (2, 'Mohamed'), (3, 'Eslam')
insert into #books
values (122, 'c#', 1), (233, 'Java', 1),
(555, 'c ', 1), (666, 'photoshop', 2),
(777, 'asp.net', 2), (888, 'python', 2)
select
a.authorName,
count(b.BookName) as countBooks,
count(bu.BookName) as countBooksUpdate,
(count(bu.BookName) count(b.BookName)) as Total
from
#Authors a
left join
#books b on a.AuthorId = b.AuthorId
left join
#booksUpdate bu on a.AuthorId = bu.AuthorId
group by
a.authorName
Вывод:
authorName countBooks countBooksUpdate Total
--------------------------------------------------
Ahmed 9 9 18
Eslam 0 0 0
Mohamed 3 0 3
Результат неверен для автора Ahmed
.
Это должно быть
authorName countBooks countBooksUpdate Total
-------------------------------------------------
Ahmed 3 3 6
Как исправить запрос, чтобы возвращать правильный результат?
Ожидаемый результат
authorName countBooks countBooksUpdate Total
-------------------------------------------------
Ahmed 3 3 6
Eslam 0 0 0
Mohamed 3 0 3
Комментарии:
1. Почему вы размещаете похожие вопросы на разных форумах и не принимаете ответы? Я вижу этот вопрос и этот другой в Microsoft Q amp; A.
2. В сторону: обычно это имеет больше смысла
group by AuthorId
, а неAuthorName
. Это позволяет разделить нескольких авторов с одинаковым именем и, в некоторых случаях, может устранить необходимость присоединения кAuthors
таблице.
Ответ №1:
Это работает. Не хватало соединения по идентификатору книги между #books и #booksUpdate
select a.authorName,count(b.BookName) as countBooks,
count(bu.BookName) as countBooksUpdate,
(count(bu.BookName) count(b.BookName)) as Total
from #Authors a
left join #books b on a.AuthorId=b.AuthorId
left join #booksUpdate bu on a.AuthorId=bu.AuthorId
and b.BookId=bu.BookId
group by a.authorName;
Результаты
authorName countBooks countBooksUpdate Total
Ahmed 3 0 3
Eslam 0 0 0
Mohamed 3 0 3
Идентификатор книги в таблице #booksUpdate не совпадает ни с одним из идентификаторов в таблице #books. Без соединения с BookID запрос выполняет перекрестное соединение.
Предположим, что 3 строки в #booksUpdate были изменены, чтобы соответствовать 3 строкам для Ахмеда. Здесь я изменяю данные, размещенные в вопросе.
drop table if exists #booksUpdate;
go
create table #booksUpdate
(
BookId int,
BookName nvarchar(200),
AuthorId int
)
insert into #booksUpdate
values
(122,'matlab',1),
(233,'3dmax',1),
(555,'c',1)
Тогда результат был бы следующим:
authorName countBooks countBooksUpdate Total
Ahmed 3 3 6
Eslam 0 0 0
Mohamed 3 0 3
Комментарии:
1. Это правда, что запрос возвращает 0 для booksupdate count, потому что объединение по BookID не дает строк. Это и есть данные. Если бы были строки, которые случайно совпали по соответствующим ключам, то подсчет был бы положительным.