On Monday, 24 Aug 2015  2:46 AM -0400, Mark Lawrence wrote:
>> It's theoretically possible, but in that case I would be content to
>> force a difference in the title.  It should be possible to have the
>> following:
>> 
>> 'History of Scotland' | -> 'A. Jones'
>> 'History of Scotland' | -> 'T. Smith'
>> 'Manual of DOS'       | NULL
>> 
>> But, an attempt to insert another record 'Manual of DOS' with a NULL
>> author should fail.
>
> You can achieve this using a partial index[1] on the Books.title
> column, which is used only when the author is null. A test script to
> demonstrate:
>
>     create table Books(
>         id integer primary key,
>         title text collate nocase not null,
>         author references Authors(id),
>         unique(title, author)
>     );
>
>     create table Authors(
>         id integer primary key,
>         name text unique not null check(name <> '')
>     );
>
>     -- **************************************************
>     create unique index no_author_index on Books(title)
>     where author is null;
>     -- **************************************************
>
>     insert into Authors values(1,'A. Jones');
>     insert into Authors values(2,'T. Smith');
>
>     insert into Books values(1, 'History of Scotland', 1);
>     insert into Books values(2, 'History of Scotland', 2);
>     insert into Books values(3, 'Manual of DOS', NULL);
>
>     select
>         b.title, a.name
>     from
>         Books b
>     left join
>         Authors a
>     on
>         a.id = b.author
>     ;
>     -- title                name      
>     -- -------------------  ----------
>     -- History of Scotland  A. Jones  
>     -- History of Scotland  T. Smith  
>     -- Manual of DOS        NULL      
>
>     insert into Books values(4, 'Manual of DOS', NULL);
>     -- Error: near line 37: UNIQUE constraint failed: Books.title
>
> [1] https://www.sqlite.org/partialindex.html

Yes, this works and seems to me to be more elegant than my original
idea of replacing a NULL author field with a 0, so thanks to you and
to the others who responded with their suggestions.

-- 
Will

Reply via email to