在没有限制的特定日期之后让第一个人死亡并获取

时间:2018-01-19 12:46:26

标签: sql postgresql

我有一张这样的表:

 PERSON (
   id,
   name,
   last_name,
   birth_date_year, 
   birth_date_month, 
   birth_date_day, 
   death_date_year, 
   death_date_month, 
   death_date_day
 )

我必须编写一个PostgreSQL查询,让第一个人死于另一个人之后(例如'让'第一个人死在'John Smith之后')。

我不能使用所有SQL构造函数(基本上只使用W3C Schools中的函数)而不能使用OFFSET,LIMIT,ROWNUM,FETCH和TOP。 允许子查询。

PS:结果表必须只有一个人,并不是所有人都按照“约翰·史密斯”按年,月,日排序。 我不能使用LIMIT,因为请求明确表示不使用它。 我不知道为什么数据存储了3个字段,只保留了一个数据字段,原始数据库不是我的。

我可以通过这个简单的查询让'John Smith'之后的所有人死亡:

select person.birth_date_year, 
   person.birth_date_month, 
   person.birth_date_day, 
   person.death_date_year, 
   person.death_date_month, 
   person.death_date_day
from person
inner join person as "dead_person" on "dead_person"."name" = 'John Smith'
where
  person.end_date_year > "dead_person".death_date_year
  or (person.death_date_year = "dead_person".death_date_year
  and person.death_date_month > "dead_person".death_date_month)
  or (person.death_date_year = "dead_person".death_date_year
  and person.death_date_month = "dead_person".death_date_month
  and person.death_date_day > "dead_person".death_date_day);
order by person.death_date_year, 
  person.death_date_month, 
  person.death_date_day

但我不知道如何在不使用LIMIT,FETCH或ROWNUM的情况下只从第一个人那里得到死亡。 在其他情况下,我使用MAX或MIN来获取最大/最小值并再次将其与表进行比较以获得完整行,但在这种情况下我无法使用它,因为我必须从3获得最低值字段而不是1和max / min不接受多列值。

1 个答案:

答案 0 :(得分:0)

我误解了这个问题。你不能使用ROWNUM。

所以,还有其他解决方案(总有另一个:))。不简单,不美观,但有效:

DROP TABLE PERSON

CREATE TABLE PERSON (
   id int,
   name varchar,
   last_name varchar,
   birth_date_year int, 
   birth_date_month int, 
   birth_date_day int, 
   death_date_year int, 
   death_date_month int, 
   death_date_day int
 )

 INSERT INTO PERSON VALUES(1, 'John','Smith',2000,1,1,2040,2,2);
 INSERT INTO PERSON VALUES(2, 'A','Aa',2000,1,1,2041,2,2);
 INSERT INTO PERSON VALUES(3, 'B','Ba',2000,1,1,2040,1,2);
 INSERT INTO PERSON VALUES(4, 'C','Ca',2000,1,1,2040,4,2);
 INSERT INTO PERSON VALUES(5, 'D','Da',2000,1,1,2040,4,2);

SELECT *
FROM person
INNER JOIN (
    -- select first id that die at same day, after 'John Smith' 
    SELECT min(person.id) id
    FROM (
        select "dead_person".id, min (make_timestamp(person.death_date_year, person.death_date_month, person.death_date_day, 0, 0, 0)) date_dead
        from person
        inner join person as "dead_person" on "dead_person".name ||  ' ' || "dead_person".last_name = 'John Smith'
        where
          person.death_date_year > "dead_person".death_date_year
          or (person.death_date_year = "dead_person".death_date_year
          and person.death_date_month > "dead_person".death_date_month)
          or (person.death_date_year = "dead_person".death_date_year
          and person.death_date_month = "dead_person".death_date_month
          and person.death_date_day > "dead_person".death_date_day)
        group by "dead_person".id
    ) dead_after
    INNER JOIN person
        ON dead_after.date_dead = make_timestamp(person.death_date_year, person.death_date_month, person.death_date_day, 0, 0, 0)
) dead_after
    ON dead_after.id = person.id