SQLite Forum

SELECT question
Login
Note also that if you want your concat of the keywords to be alphabetical you would use this:

```
  select docs.id, docs.title AS Title, authors.author AS Author, docs.source AS Source,
         (
          select group_concat(keyword)
            from (
                    select keyword
                      from keywords
                     where docid = docs.docid
                       and authorid = docs.Authorid
                  order by keyword
                 )
         )
    from docs, authors
   where docs.authorid = authors.authorid
     and docs.docid = authors.docid
order by docs.id desc
   limit 5;
```

I would also point out that usually the relationship between "docs" and "authors" is N:M, as is the relationship between "docs" and "keywords".  That is, an "author" can write many "docs" and a "doc" may have many authors.  However the "Isaac Asimov" that wrote one "doc" may be the same author as wrote another "doc" -- you current scheme is subject to update anomalies because it requires separate "Isaac Asimov" in the authors table despite there only being one such author.  Mutatis Mutandis keywords.

The usual way to do this in a Relational Database is to have a "linkage table" which enumerates the N:M linkages thus:

```
create table authors
(
  authorid integer primary key,
  name     text collate nocase unique
);
create table keywords
(
   keywordid integer primary key,
   keyword   text collate nocase unique
);
create table docs
(
  docid  integer primary key,
  title  text collate nocase unique
);
create table docauthors
(
   docid    integer not null references docs on delete cascade,
   authorid integer not null references authors on delete cascade,
   unique (docid, authorid),
   unique (authorid, docid)
);
create table dockeywords
(
   docid     integer not null references docs on delete cascade,
   keywordid integer not null references keywords on delete cascade,
   unique (docid, keywordid),
   unique (keywordid, docid)
);
```

In this way you can have multiple authors per docs, multiple docs per authors, multiple keywords per docs, and multiple docs per keywords.

You can also retrieve multiple keywords per authors or multiple authors per keywords.

Note that you could declare the linkage tables differently to conserve disk space by storing only 2 b-tree's per linkage rather than 3:

```
create table docauthors
(
   docid    integer not null references docs on delete cascade,
   authorid integer not null references authors on delete cascade,
   primary key (docid, authorid),
   unique (authorid, docid)
) without rowid;
create table dockeywords
(
   docid     integer not null references docs on delete cascade,
   keywordid integer not null references keywords on delete cascade,
   primary key (docid, keywordid),
   unique (keywordid, docid)
) without rowid;
```