我有一张这样的表:
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不接受多列值。
答案 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