如何在`where`子句

时间:2016-11-21 10:32:12

标签: sqlite

在sqlite3中,我将新表中各种表的条目组合在一起(使用主键和外键的contsraints;有关详细信息,请参见底部):

select * from files;
id          file            description       
----------  --------------  ----------------  
1           testmodel1.dat  first test model
2           testmodel2.dat  second test mode

select * from patches;
id          patch        description
----------  ----------  ------------
1           testpatch   test patch

组合表:

select * from patched_files;
id          files_id    patches_id
----------  ----------  ----------
1           1           NULL
2           1           1
3           2           1

有些文件会被修补一些(有时是同一个文件)。

我想从数据库中检索此视图(预期结果):

id          file            patch
----------  --------------  ----------
1           testmodel1.dat  
2           testmodel1.dat  testpatch
3           testmodel2.dat  testpatch

我试过了:

select patched_files.id as id,patched_files.files_id as file_id, files.file as file, patched_files.patches_id as patch_id, patches.patch as patch 
from patched_files, files, patches 
where patched_files.files_id=files.id and patched_files.patches_id=patches.id;

id          files_id    file            patches_id  patch
----------  ----------  --------------  ----------  ----------
2           1           testmodel1.dat  1           testpatch
3           2           testmodel2.dat  1           testpatch

在这里,我缺少未修补的文件(rowid 1),我理解为什么。 所以我添加了or

select patched_files.id as id,patched_files.files_id as file_id, files.file as file, patched_files.patches_id as patch_id, patches.patch as patch 
from patched_files, files, patches 
where patched_files.files_id=files.id and (patched_files.patches_id=patches.id or patched_files.patches_id is NULL);

id          file_id     file            patch_id    patch
----------  ----------  --------------  ----------  ----------
1           1           testmodel1.dat  NULL        testpatch
2           1           testmodel1.dat  1           testpatch
3           2           testmodel2.dat  1           testpatch

我理解为什么会这样(来自“文件”和“补丁”的复合表)。

如果patch_id为NULL,如何避免声明补丁名称? 我是否需要在“补丁”表中插入“虚拟”?

重新创建示例:

-- original files:
create table files (id integer primary key, file text, description text);
insert into  files (file, description) values('testmodel1.dat', 'first test model');
insert into  files (file, description) values('testmodel2.dat', 'second test model');
-- patches:
create table patches (id integer primary key, patch text, description text);
insert into  patches (patch, description) values('testpatch', 'test patch');
-- patched files (combination of files and patches):
create table patched_files (id integer primary key, files_id integer references files(id) on delete restrict deferrable initially deferred, patches_id integer references patches(id) on delete restrict deferrable initially deferred);
insert into  patched_files (files_id) values(1);
insert into  patched_files (files_id, patches_id) values(1,1);
insert into  patched_files (files_id, patches_id) values(2,1);

1 个答案:

答案 0 :(得分:0)

您正在寻找外部联接:

select f.id, f.file, p.patch, p.description
from files f 
  left join patched_files pf on pf.files_id = f.id
  left join patches p on p.id = pf.patches_id

在线示例:http://rextester.com/ZNMAY53081