I have got the database which has id,chapter_name,chapter_num,verse_num,verse_text,testament as columns.
I would like to retrieve chapterName and the total number of chapters in each book.
I’m using the following query to do so,
select chapter_name, count(chapter_name) from TABLE_NAME group by chapter_num;
Unfortunately, it lists a very big count of chapter names and duplicate chapter names as well. How can I fix this? This is the sample input
id,chapter_name,chapter_num,verse_num,verse_text,testament 
1, "Genesis", 1, 1, "text", 0 1, "Genesis", 1, 2, "text", 0 1, "Genesis", 1, 3, "text", 0 . . . 1, "Revelation", 1, 1, "text", 0
The output should be,
`id`, `chapter_name`,`count(chapter_name)` 1, 'Genesis', 50 2, 'Exodus' 40 . . 66 'Revalation ' 21
Advertisement
Answer
This is a table of verses with redundant chapter (chapter_num) and book (chapter_name) information. We must first eliminate the redundancy and get a single row for each book and chapter. Then we can count them.
select
  chapter_name,
  count(chapter_num)
from (
  select
    chapter_name,
    chapter_num
  from verses
  group by chapter_name, chapter_num
)
group by chapter_name;
Redundancy indicates a poorly designed schema. There’s three pieces of information, so there should be three tables: book, chapter, verse.
create table books ( id integer primary key, name text not null ); create table chapters ( id integer primary key, num integer not null, book_id integer not null references books(id), unique(book_id, num) ); create table verses ( id integer primary key, num integer not null, content text not null, chapter_id integer not null references chapters(id), unique(chapter_id, num) );
Now if we want to find how many chapters are in each book…
select books.name, count(chapters.id) from books join chapters on chapters.book_id = books.id group by books.id
Or how many verses are in each book…
select books.name, count(verses.id) from books join chapters on chapters.book_id = books.id join verses on verses.chapter_id = chapters.id group by books.id