检查其他表中是否不存在值

时间:2020-04-28 05:53:58

标签: sql postgresql entity-relationship

你好,我有以下问题。

我有这张ER图 enter image description here

我需要选择所有在发表博士学位论文的年份未发表期刊或会议论文的人员(PhD是“论文”中的类型字段)。我的问题是,当我仅检查他是否未发表论文时,我就实现了,但是当我两个都失败时,我该怎么办?

Select count(akey)
from persons 
WHERE (Select theses.year 
       from persons 
          inner join theses on persons.akey = theses.akey 
       Where theses.type = 'PhD') not in ((Select year 
           from persons 
             inner join authpapers on persons.akey = authpapers.akey 
             inner join papers on authpapers.pkey = papers.pkey 
             inner join journals on journals.jkey = papers.jkey) 
 and (Select year 
      from persons 
        inner join authpapers on persons.akey = authpapers.akey 
        inner join papers on authpapers.pkey = papers.pkey 
        inner join conferences on conferences.ckey = papers.ckey));

它说不是从in开始的部分不是布尔类型,但是我应该怎么做呢?

3 个答案:

答案 0 :(得分:0)

您的NOT IN子句基本上可以减少到NOT IN (queryResultJournals AND queryResultPapers)。它试图对两个查询结果进行“与”运算,这不是您想要的(这就是为什么您得到的不是布尔错误)的原因。您应该将和替换为UNION或UNION ALL,将两个查询结果合并为一个,然后在NOT IN子句中使用。

Select count(akey)
from persons 
WHERE (Select theses.year 
       from persons 
          inner join theses on persons.akey = theses.akey 
       Where theses.type = 'PhD') not in ((Select year 
           from persons 
             inner join authpapers on persons.akey = authpapers.akey 
             inner join papers on authpapers.pkey = papers.pkey 
             inner join journals on journals.jkey = papers.jkey) 
 UNION (Select year 
      from persons 
        inner join authpapers on persons.akey = authpapers.akey 
        inner join papers on authpapers.pkey = papers.pkey 
        inner join conferences on conferences.ckey = papers.ckey));

答案 1 :(得分:0)

仅显示一种替代方法:您可以收集所有出版物(论文,会议和期刊),然后进行汇总以查找在一年内发表论文的人以及会议或期刊。

with published as
(
  select akey, type, year from theses where type = 'PhD'
  union all
  select ap.akey, 'conference', c.year
  from authpapers ap 
  join papers p on p.pkey = ap.pkey
  join conferences c on c.ckey = p.ckey
  union all
  select ap.akey, 'journal', j.year
  from authpapers ap 
  join papers p on p.pkey = ap.pkey
  join journals j on c.jkey = p.jkey
)
select *
from persons
where akey in
(
  select akey
  from published
  group by akey, year
  having bool_or(type = 'PhD')
  and not ( bool_or(type = 'conference') or bool_or(type = 'journal') )
)
order by akey;

聚合bool_or可以理解为“至少一个”或“任何”。

我们不知道您的数据库是否允许将同一篇论文同时发表为Jounal和Conference。或者一个人是否可以拥有多个博士学位论文(也许是几次尝试?)。上面的查询查找了某人发表某年的所有年份,如果发现某人至少发表了一篇博士学位论文和期刊或会议,则显示该人。

答案 2 :(得分:0)

如果可以使用exists()

,则无需计数
SELECT *
from persons pe -- I need to select all the persons
WHERE NOT EXISTS (SELECT SELECT * -- that did not
       FROM theses th 
        JOIN authpapers ap on pe.akey = ap.akey
        JOIN papers pa on ap.pkey = pa.pkey 
        JOIN journals jo on jo.jkey = pa.jkey -- publish a journal paper
        WHERE th.type = 'PhD'
        AND th.akey = pe.akey
        AND th.year = jo.year  -- in the same year
        )
 AND NOT EXISTS (SELECT *
        FROM theses th
        JOIN authpapers ap on pe.akey = ap.akey
        JOIN papers pa on ap.pkey = pa.pkey
        JOIN conferences co on co.ckey = pa.ckey  -- or publish a conference paper
        WHERE th.type = 'PhD'
        AND th.akey = pe.akey
        AND th.year = co.year -- in the same year
        );