对于一个项目,我必须在SQL中编写一个查询(在PostgreSQL上),该查询检索第一位死于艺术家的艺术家,名为“Louis Armstrong”。 在查询中,我不能使用FETCH,TOP,ROWNUM,LIMIT。
这些是我的表
ARTIST
ID(PK)
GID(PK)
NAME(PK)
SORT_NAME(PK)
BEGIN_DATE_YEAR
BEGIN_DATE_MONTH
BEGIN_DATE_DAY
TYPE(FK) --(TYPE NUMBER)
ARTIST_TYPE
ID(PK)
NAME(PK)--(PERSON,GROUP,OTHER)
这是我写下的查询,是正确的,但我不能使用LIMIT子句
SELECT A.NAME,
CONCAT_WS('/',A.BEGIN_DATE_DAY::text,A.BEGIN_DATE_MONTH::text,
A.BEGIN_DATE_YEAR::text) AS DATA_NASCITA,
CONCAT_WS('/',A.END_DATE_DAY::text,A.END_DATE_MONTH::text,
A.END_DATE_YEAR::text) AS DATA_MORTE
FROM artist AS A
JOIN artist_type AS AT ON A.TYPE = AT.ID
WHERE AT.NAME LIKE 'Per%' AND A.END_DATE_YEAR > ALL
(SELECT A.END_DATE_YEAR FROM artist AS A
JOIN artist_type AS AT ON A.TYPE = AT.ID
WHERE AT.NAME LIKE 'Per%' AND A.END_DATE_YEAR <= ALL
(
SELECT A.END_DATE_YEAR FROM artist AS A
JOIN artist_type AS AT ON A.TYPE = AT.ID
WHERE AT.NAME LIKE 'Per%' AND A.NAME LIKE 'Lou%'
)
)
ORDER BY A.END_DATE_YEAR ASC
LIMIT 1
答案 0 :(得分:0)
如果你想制作令人费解的慢代码,你可以试试这个......
SELECT DISTINCT
FIRST_VALUE(
A.NAME
) OVER END_DATE_YEAR_ASC
AS NAME,
FIRST_VALUE(
CONCAT_WS('/',A.BEGIN_DATE_DAY::text,A.BEGIN_DATE_MONTH::text,A.BEGIN_DATE_YEAR::text)
) OVER END_DATE_YEAR_ASC
AS DATA_NASCITA,
FIRST_VALUE(
CONCAT_WS('/',A.END_DATE_DAY::text,A.END_DATE_MONTH::text,A.END_DATE_YEAR::text)
) OVER END_DATE_YEAR_ASC
AS DATA_MORTE
FROM
<your query, without the ORDER BY>
WINDOW
END_DATE_YEAR_ASC AS (ORDER BY A.END_DATE_YEAR)
但是,WHERE
条款“可疑”......
首先...
> ALL(<some dates)
== > ( MAX(<some_dates>) )
<= ALL(<some dates)
== <= ( MIN(<some_dates>) )
除非你期待NULL
在那里?
所以,这给了......
WHERE
AT.NAME LIKE 'Per%'
AND A.END_DATE_YEAR
>
(
# Latest [END_DATE_YEAR]
# Where that [END_DATE_YEAR] is before (or equal to)
# Earliest [END_DATE_YEAR] for 'Lou%'
############################################################
SELECT MAX(A.END_DATE_YEAR)
FROM artist AS A
JOIN artist_type AS AT ON A.TYPE = AT.ID
WHERE AT.NAME LIKE 'Per%'
AND A.END_DATE_YEAR
<=
(
# Earliest [END_DATE_YEAR] for 'Lou%'
############################################################
SELECT MIN(A.END_DATE_YEAR)
FROM artist AS A
JOIN artist_type AS AT ON A.TYPE = AT.ID
WHERE AT.NAME LIKE 'Per%'
AND A.NAME LIKE 'Lou%'
)
)
Lou%
艺术家的最早死亡日期。这不是第一个'Lou%'
死亡的死亡吗?
答案 1 :(得分:0)
我认为你被禁止使用FETCH, TOP, ROWNUM, LIMIT
所以这只是使用过的逻辑问题,尝试重现这个伪代码:
select *
from artists a
where a.deathDate > (select deatheDate from artists where name = 'Louis Armstrong')
and not exists (
select 1
from artists b
where b.deathDate < a.deathDate
)
警告! 可以有多个匹配您的条件。
答案 2 :(得分:0)
我相信你打算写的......
WITH
artist_per AS
(
SELECT *
FROM artist AS A
JOIN artist_type AS AT ON AT.ID = A.TYPE
WHERE AT.name LIKE 'Per%'
)
SELECT
NAME,
CONCAT_WS('/',BEGIN_DATE_DAY::text,BEGIN_DATE_MONTH::text,BEGIN_DATE_YEAR::text) AS DATA_NASCITA,
CONCAT_WS('/', END_DATE_DAY::text, END_DATE_MONTH::text, END_DATE_YEAR::text) AS DATA_MORTE
FROM
artist_per
WHERE
END_DATE = (
SELECT MIN(END_DATE)
FROM artist_per
WHERE END_DATE > (
SELECT MIN(END_DATE)
FROM artist_per
WHERE NAME LIKE 'Lou%'
)
)
如果只有一个人在Lou%
死后立即死亡,将返回一行。