首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >尝试编写一个查询,显示连续两年内发表论文的所有作者的姓名

尝试编写一个查询,显示连续两年内发表论文的所有作者的姓名
EN

Stack Overflow用户
提问于 2020-05-03 13:33:14
回答 3查看 73关注 0票数 0

维护作者和出版物信息的数据库具有以下架构:

代码语言:javascript
复制
CREATE TABLE Author (aid integer NOT NULL,
name varchar(50) NOT NULL,
affiliation varchar(50), primary key(aid));

CREATE TABLE Paper (pid  integer NOT NULL,
title varchar(50) NOT NULL,
year integer NOT NULL, primary key(pid));

CREATE TABLE Authored (aid integer references Author,
pid integer references Paper,
primary key(aid, pid), foreign key(aid) references Author(aid), foreign key(pid) references Paper(pid));

insert into Author(aid, name, affiliation) values (1, "A", "DS");
insert into Author(aid, name, affiliation) values (2, "B", "PS");
insert into Author(aid, name, affiliation) values (3, "C", "CS");

insert into Paper(pid, title, year) values (100, "DS1", 2019);
insert into Paper(pid, title, year) values (101, "PS1", 2019);
insert into Paper(pid, title, year) values (102, "CS1", 2019);
insert into Paper(pid, title, year) values (103, "DS2", 2020);
insert into Paper(pid, title, year) values (104, "PS2", 2020);
insert into Paper(pid, title, year) values (105, "CS2", 2019);

Authored.aidAuthor的外键,Authored.pidPaper的外键。

我正在尝试编写一个查询,打印连续两年发表论文的所有作者的姓名。这是我到目前为止所拥有的,但它似乎过于复杂。

代码语言:javascript
复制
select au1.aid as id, a1.name as name
from authored au1 
inner join authored au2 on au1.aid = au2.aid
inner join author a1 on au1.aid = a1.aid
inner join paper p1 on au1.pid = p1.pid
inner join paper p2 on au2.pid = p2.pid
where p1.year = p2.year + 1
order by au1.aid;
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-05-03 20:51:49

我会使用lag()。要获取作者ids,请执行以下操作:

代码语言:javascript
复制
select p.aid
from (select a.aid, p.year,
             lag(p.year) over (partition by a.aid order by p.year) as prev_year
      from papers p join
           authored a
           on a.pid = p.pid
      group by a.aid, p.year
     ) p
where prev_year = year - 1

然后,您可以使用injoin或其他任何工具来获取完整的作者信息:

代码语言:javascript
复制
select a.*
from authors a
where a.aid in (select a.aid
                from (select a.aid, p.year, 
                             lag(p.year) over (partition by a.aid order by p.year) as prev_year
                      from papers p join
                           authored a
                           on p.pid = a.pid
                      group by a.aid, p.year
                     ) p
                where prev_year = year - 1
               );

你实际上不需要滞后,但它可能会更有效率。另一种选择是:

代码语言:javascript
复制
with pa as (
      select p.*, a.aid
      from papers p join
           authors a
           on p.pid = p.pid
     )
select a.*
from authors a
where a.aid in (select p.aid
                from pa p join
                     pa p_prev
                     on p_prev.aid = p.aid and
                        p_prev.year = p.year - 1
               );
票数 0
EN

Stack Overflow用户

发布于 2020-05-03 13:43:34

尝试下面的方法,它看起来像是鸿沟和孤岛问题。这是一个小的示例demo,它将让您了解如何解决您的问题。

代码语言:javascript
复制
select
    id,
    name
from
(
    select
        aid,
        name,
        count(*) over (partition by rnk) as total
    from
    (
        select 
            aid as id, 
            name,
            year - row_number() over (partition by aid, name order by year) as rnk
        from authored au            

        inner join author a
        on au.aid = a.aid

        inner join paper p
        on au.pid = p.pid
    ) val
) fin
where total = 2
票数 0
EN

Stack Overflow用户

发布于 2020-05-03 14:19:55

看起来没那么复杂

代码语言:javascript
复制
SELECT au1.aid as id, au1.name AS name
FROM author au1 INNER join authored authored1 ON au1.aid=authored1.aid
INNER join paper p1 ON authored1.pid=p1.pid
WHERE au1.aid IN (SELECT au2.aid FROM author au2 
                  INNER join authored authored2 ON au1.aid=authored2.aid
                  INNER join paper p2 ON au2.pid=p1.pid AND  p2.year = p1.year+1)
ORDER by au1.aid;

您也可以使用SQL EXISTS而不是IN

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61570032

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档