SQL - 选择另一个表中不存在的记录(3表关系)

时间:2016-01-14 12:31:13

标签: sql sql-server

我有3张桌子:

this.newListingForm = fb.group({
  'typeRadio': ['',  Validators.compose([Validators.required, Validators.minLength(2), Validators.maxLength(40)])],
  'mainTitleInput': ['', Validators.compose([Validators.required, Validators.minLength(2), Validators.maxLength(40)])],
  'emailAddressInput': ['', Validators.compose([Validators.required, Validators.minLength(2), Validators.maxLength(40)])],
});

我想选择所有 NOT 的汽车在Table_CarDocuments上有4个特定id_documentType的文档。

这样的事情:

Table_Cars
-id_car
-description

Table_CarDocuments
-id_car
-id_documentType
-path_to_document

Table_DocumentTypes
-id_documentType
-description

有了这个,我知道我错过了car1的2个文件和car2的1个文件。

4 个答案:

答案 0 :(得分:2)

您正在寻找丢失的汽车文件。因此,交叉加入汽车和文档类型,并在汽车挂牌表中查找组合。

select c.description as car, dt.description as doctype
from table_cars c
cross join table_documenttypes dt
where (c.id_car, dt.id_documenttype) not in
(
  select cd.id_car, cd.id_documenttype
  from table_cardocuments cd
);

更新:它表明SQL Server的IN子句非常有限,无法处理值列表。但NOT IN子句很容易被NOT EXISTS替换:

select c.description as car, dt.description as doctype
from table_cars c
cross join table_documenttypes dt
where not exists
(
  select *
  from table_cardocuments cd
  where cd.id_car = c.id_car
  and cd.id_documenttype = dt.id_documenttype
);

更新:由于您只对特定的id_documenttype感兴趣(您必须为查询添加and dt.id_documenttype in (1, 2, 3, 4)),您可以即时为它们生成记录,而不必阅读table_documenttypes

为了做到替换

cross join table_documenttypes dt

cross join (values (1), (2), (3), (4)) as dt(id_documentType)

答案 1 :(得分:1)

您可以使用以下查询获得结果:

SELECT
    c.description,
    dt.description
FROM
    Table_Cars c
    JOIN Table_CarDocuments cd ON c.id_car = cd.id_car
    JOIN Table_DocumentTypes dt ON cd.id_documentType = dt.id_documentType
WHERE
    dt.id_documentType NOT IN (1, 2, 3, 4) --replace with your document type id

答案 2 :(得分:0)

这可能是一个复杂的查询。我们的想法是生成汽车的所有组合和您想要的四个文档(使用cross join)。然后使用left join确定文档是否确实存在:

select c.id_car, dd.doctype
from cars c cross join
     (select 'doc1' as doctype union all
      select 'doc2' union all
      select 'doc3' union all
      select 'doc4'
     ) dd left join
     CarDocuments cd
     on c.id_car = cd.id_car left join
     Documents d
     on cd.id_document_type = d.id_document_type and d.doctype = dd.doctype
where dd.id_document_type is null;

最后,where子句找到数据中不存在的car / doctype对。

答案 3 :(得分:0)

感谢@Thorsten Kettner的帮助

select c.description as car, dt.description as doctype
from table_cars c
cross join table_documenttypes dt
where dt.id no in (
(
  select cd.id_documentType
  from table_cardocuments cd
  where cd.idcar = c.id AND cd.id_doctype = dt.id
)
AND dt.id IN (1, 2, 3, 4)