Проверьте, не существует ли значение в других таблицах - PullRequest
1 голос
/ 28 апреля 2020

Здравствуйте, у меня есть следующая проблема.

У меня есть эта ER-диаграмма enter image description here

Мне нужно выбрать всех людей, которые не публиковались sh журнал или документ конференции в том году, в котором они опубликовали свои кандидатские диссертации (PhD - типовое поле в диссертациях) Моя проблема в том, что я достиг этого, когда я проверяю, не опубликовал ли он sh бумагу, но когда у меня есть оба, я терплю неудачу, что я делаю не так?

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));

В нем говорится, что часть начинается с не в не тип логического, но как мне сделать это иначе?

Ответы [ 3 ]

1 голос
/ 28 апреля 2020

Ваше предложение 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));
0 голосов
/ 28 апреля 2020

Вам не нужно считать, если вы можете использовать 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
        );
0 голосов
/ 28 апреля 2020

Просто чтобы показать альтернативу: вы можете собрать все публикации (тезисы, конференции и журналы), а затем объединить их, чтобы найти людей, которые за один год опубликовали свои тезисы, плюс конференции или журналы.

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 может читаться как «по крайней мере один» или «любой».

Мы не знаем, допускает ли ваша база данных один и тот же документ, выпущенный как для заседаний, так и для конференций. Или может ли человек иметь несколько кандидатских диссертаций (может быть, несколько попыток?). Над запросом рассматриваются все годы, когда человек что-то публиковал, и если он обнаружил, что хотя бы один год человек опубликовал диссертацию на соискание ученой степени кандидата наук и журналы или конференции, он показывает этого человека.

...