2015-08-04 2 views
0

У меня есть таблица разделов, в которой содержится около 17 записей, принадлежащих одной книге.Значения MySQL COUNT изменяются, когда JOINING

chapters: 
-------------------------- 
| id | book_id | content | 
-------------------------- 
| 1 | 1 | ... | 
| 2 | 1 | ... | 
| 3 | 1 | ... | 
| 4 | 1 | ... | 
| 5 | 1 | ... | 
| ... | 1 | ... | 
-------------------------- 

Существует также библиотека таблица, которая связывает пользователей к книгам, которые они сохранили:

library: 
---------------- 
| user | book_id | 
---------------- 
| 1 | 1 | 
| 1 | 2 | 
| 2 | 1 | 
| 3 | 1 | 
| 4 | 1 | 
| ... | 1 | 
---------------- 

можно использовать:

SELECT COUNT(*) FROM chapters WHERE book_id = 1 

и таблица правильно выводит 17, потому что книги 1 имеет 17 глав

Если да, то:

SELECT COUNT(*) FROM library WHERE book_id = 1 

Я также получаю правильный результат 5, потому что 5 пользователей добавили книгу 1 в свою библиотеку.

Однако я не могу объединить два запроса вместе, используя JOIN. Я хочу, чтобы код SQL, который будет выводить что-то вроде этого:

output: 
----------------------------- 
| book | chapters | readers | 
----------------------------- 
| 1 | 17 | 5 | 
----------------------------- 
+0

Ваша модель пропускает 'books' таблицу, которая должна хранить' book_id', название книги и автор и т.д. Your ' library' table - таблица ассоциаций, созданная для отношений «многие-ко-многим» между книгами и пользователями. – axiac

+0

@axiac Таблица книг не должна хранить автора. – Strawberry

+1

@ Струберри, ты прав. Я сделал ту же ошибку, что и OP :-) – axiac

ответ

0
select c.book_id, count(c.id) as chapters, count(l.user) as readers 
from chapters c 
join library l on l.book_id = c.book_id 
where c.book_id = 1 
group by c.book_id 
+0

Нет, похоже, я получаю book_id = 1, chapters = 17, reader = 17 – user2352119

+0

Вы забыли добавить в круглые скобки числа. И группа в этом случае не нужна. Должно быть так: выберите c.book_id, count (distinct c.id) в качестве глав, счетчик (отдельный l.user) в качестве читателей –

0

// Проверяет ниже:

select "1" as book, 
    (SELECT COUNT(*) FROM chapters WHERE book_id = 1) as chapters, 
    (SELECT COUNT(*) FROM library WHERE book_id = 1) as readers 
from dual; 
+0

ненужных подзапросов, дорогих по сравнению с простым внутренним соединением. – Dunney

+0

Два счета в большой базе данных должны быть менее дорогими, чем объединение с агрегатными функциями. –

0

Если попытался запрос, как показано ниже результирующего набора будет включать все строки в libary и главах в этом случае 85 строк (17x5):

select c.book_id, c.id as chapters, l.user as readers 
from chapters c 
inner join library l on l.book_id = c.book_id 
where c.book_id = 1; 

Внутреннее соединение SELEC ключевое слово ts все строки из обеих таблиц, если существует совпадение между столбцами в обеих таблицах.

Вы можете прочитать больше Here.

Однако для того, чтобы получить уникальное количество строк, т.е. 17 глава и 5 читателей из вашего результата 85 набор записей вы должны использовать подсчитывать различны, как показано ниже:

select c.book_id, count(distinct(c.id)) as chapters, count(distinct(l.user)) as readers 
from chapters c 
inner join library l on l.book_id = c.book_id 
where c.book_id = 1; 

Вы можете прочитать больше о подсчете отчетливого here.

+0

Не могли бы вы пояснить, почему этот код отвечает на вопрос? Кодовые ответы [обескуражены] (http://meta.stackexchange.com/q/148272/274165), потому что они не учат решению. –

0

Существует ответ:

select c.book_id, count(distinct c.id) as chapters, count(distinct l.user) as readers 
from chapters c 
left join library l on l.book_id = c.book_id 
where c.book_id = 1 

или для всех книг:

select c.book_id, count(distinct c.id) as chapters, coalesce(count(distinct l.user), 0) as readers 
from chapters c 
left join library l on l.book_id = c.book_id 
group by c.book_id 
Смежные вопросы