在子查询中使用 row_number() 导致 ORA-00913: 值太多
Using row_number() in subquery results in ORA-00913: too many values
在 Oracle 中,我希望执行类似下面的 SQL 的操作。对于 "criteria," 中的每一行,我想在另一个 table(按 last_modified_date)中找到相同 location_id 的最新行,并使用该值设置 default_start_interval.或者,如果没有这样的值,则使用 30。但是,如您所见,子查询必须在 select 语句中有两个值才能使用 row_number()。这会导致错误。我如何重新格式化它才能正常工作?
update criteria pc set default_start_interval =
COALESCE(
(SELECT start_interval,
row_number() over(partition by aday.location_id
order by atime.last_modified_date desc
) as rn
FROM available_time atime
JOIN available_day aday ON aday.available_day_id = atime.available_day_id
WHERE aday.location_id = pc.location_id
and rn = 1)
, 30)
您的更新查询中有两个问题:
更新预计 default_start_interval 每行只有一个值,但是 select 列表中有两列。
行号应该在内层查询之前分配,然后在外层查询应用过滤器where rn = 1
。
您的更新查询应如下所示:
UPDATE criteria pc
SET default_start_interval = NVL(
(
SELECT start_interval FROM(
SELECT
start_interval, ROW_NUMBER() OVER(
PARTITION BY aday.location_id
ORDER BY atime.last_modified_date DESC
) AS rn
FROM
available_time atime
JOIN available_day aday ON aday.available_day_id = atime.available_day_id
WHERE
aday.location_id = pc.location_id
)
WHERE rn = 1)
, 30)
注意: 您可以简单地使用 NVL
而不是 COALESCE
,因为您只有一个值来检查 NULL。当您有多个表达式时,COALESCE 很有用。
我认为更简单的方法是使用聚合和 keep
来获取您想要的值:
update criteria pc
set default_start_interval =
(select coalesce(max(start_interval) keep (dense_rank first order by atime.last_modified_date desc), 30)
from available_time atime join
available_day aday
on aday.available_day_id = atime.available_day_id
where aday.location_id = pc.location_id
);
没有 GROUP
的聚合查询总是 returns 一行。如果没有行匹配,则返回值为 NULL
——COALESCE()
捕获这种情况。
在 Oracle 中,我希望执行类似下面的 SQL 的操作。对于 "criteria," 中的每一行,我想在另一个 table(按 last_modified_date)中找到相同 location_id 的最新行,并使用该值设置 default_start_interval.或者,如果没有这样的值,则使用 30。但是,如您所见,子查询必须在 select 语句中有两个值才能使用 row_number()。这会导致错误。我如何重新格式化它才能正常工作?
update criteria pc set default_start_interval =
COALESCE(
(SELECT start_interval,
row_number() over(partition by aday.location_id
order by atime.last_modified_date desc
) as rn
FROM available_time atime
JOIN available_day aday ON aday.available_day_id = atime.available_day_id
WHERE aday.location_id = pc.location_id
and rn = 1)
, 30)
您的更新查询中有两个问题:
更新预计 default_start_interval 每行只有一个值,但是 select 列表中有两列。
行号应该在内层查询之前分配,然后在外层查询应用过滤器
where rn = 1
。
您的更新查询应如下所示:
UPDATE criteria pc
SET default_start_interval = NVL(
(
SELECT start_interval FROM(
SELECT
start_interval, ROW_NUMBER() OVER(
PARTITION BY aday.location_id
ORDER BY atime.last_modified_date DESC
) AS rn
FROM
available_time atime
JOIN available_day aday ON aday.available_day_id = atime.available_day_id
WHERE
aday.location_id = pc.location_id
)
WHERE rn = 1)
, 30)
注意: 您可以简单地使用 NVL
而不是 COALESCE
,因为您只有一个值来检查 NULL。当您有多个表达式时,COALESCE 很有用。
我认为更简单的方法是使用聚合和 keep
来获取您想要的值:
update criteria pc
set default_start_interval =
(select coalesce(max(start_interval) keep (dense_rank first order by atime.last_modified_date desc), 30)
from available_time atime join
available_day aday
on aday.available_day_id = atime.available_day_id
where aday.location_id = pc.location_id
);
没有 GROUP
的聚合查询总是 returns 一行。如果没有行匹配,则返回值为 NULL
——COALESCE()
捕获这种情况。