嵌套 SELECT 带大小写的查询
NESTED SELECT QUERY WITH CASE
请查看查询。
我面临的问题是:
THEN 子句中的 FROM_LOCATION,TO_LOCATION 需要是 B_TARIFFS 的值,但是当我在它前面加上 B_TARIFFS.FROM_LOCATION
和 B_TARIFFS.TO_LOCATION
,我得到一个 ORA-00904: Invalid identifier.
的错误。
如果它在 ELSE
子句中可用,那么为什么我不能在 THEN
子句中使用它。我该怎么做才能得到我想要的结果。
我想要的查询结果是这样的:Get from_location,to_location, tariff (based on case from another table)。我期望外部查询将其 FROM_LOCATION、TO_LOCATION 传递给 CASE ELSE THEN
中的内部 select 查询,并基于此返回关税值,这将是外部查询的第三列。我该怎么做才能实现这一目标。
select FROM_LOCATION, TO_LOCATION,
case when (
select tariff A_tariff where A_tariff.FROM_LOCATION = B_TARIFFS.FROM_LOCATION AND A_tariff.TO_LOCATION =
B_TARIFFS.TO_LOCATION AND TO_DATE(sysdate,'YYYY-MM-DD') between TO_DATE(from_date,'YYYY-MM-DD') and TO_DATE(to_date,'YYYY-MM-DD')
and rownum = 1
) = ''
then
(SELECT TARIFF FROM (
SELECT * FROM A_TARIFF WHERE TRIM(A_TARIFF.FROM_LOCATION) = TRIM(**FROM_LOCATION**) AND
TRIM(A_TARIFF.TO_LOCATION) = TRIM(**TO_LOCATION**) ORDER BY A_TARIFF.FROM_DATE DESC
) WHERE ROWNUM = 1)
else
(select tariff from A_tariff where A_tariff.FROM_LOCATION = B_TARIFFS.FROM_LOCATION AND A_tariff.TO_LOCATION =
B_TARIFFS.TO_LOCATION AND TO_DATE(sysdate,'YYYY-MM-DD') between TO_DATE(from_date,'YYYY-MM-DD') and TO_DATE(to_date,'YYYY-MM-DD')
and rownum = 1) end tariff
FROM B_TARIFFS
WHERE FROM_LOCATION LIKE '%ABC%' AND AREA_CODE = 'X' ORDER BY TARIFFS;
你的问题出在双重嵌套上。
你为什么不改变:
(SELECT TARIFF FROM (
SELECT * FROM A_TARIFF WHERE TRIM(A_TARIFF.FROM_LOCATION) = TRIM(**FROM_LOCATION**) AND
TRIM(A_TARIFF.TO_LOCATION) = TRIM(**TO_LOCATION**) ORDER BY A_TARIFF.FROM_DATE DESC
) WHERE ROWNUM = 1)
和
SELECT TARIFF FROM A_TARIFF WHERE TRIM(A_TARIFF.FROM_LOCATION) = TRIM(B_TARIFFS.FROM_LOCATION) AND
TRIM(A_TARIFF.TO_LOCATION) = TRIM(B_TARIFFS.TO_LOCATION) WHERE ROWNUM = 1
ORDER BY A_TARIFF.FROM_DATE DESC
如@alexandergs 所述,错误原因是子查询嵌套太深。但你有比这更大的问题。
在您的 when
子句中,您根据一些随机行做出决定,因为条件 rownum=1
没有排序。
else
子句也是如此。也不清楚这个 when (select ...) = ''
是什么意思——我怀疑你想展示一些不空的东西,
但目前的建设不提供这一点。您必须将查询重建为类似此处的内容:
select b.from_location, b.to_location, a.tariff, b.tariffs,
row_number() over (partition by b.from_location, b.to_location
order by a.from_date desc) rn
from b_tariffs b
left join a_tariff a
on a.from_location = b.from_location and a.to_location = b.to_location
and trunc(sysdate) between trunc(a.from_date) and trunc(a.to_date)
where b.from_location like '%ABC%' and b.area_code = 'X' order by b.tariffs;
...最终为 row_number() 添加更多代码 - 因此它会根据您的需要对行进行排序并获取 RN = 1 的行。
请查看查询。
我面临的问题是:
THEN 子句中的 FROM_LOCATION,TO_LOCATION 需要是 B_TARIFFS 的值,但是当我在它前面加上 B_TARIFFS.FROM_LOCATION
和 B_TARIFFS.TO_LOCATION
,我得到一个 ORA-00904: Invalid identifier.
的错误。
如果它在 ELSE
子句中可用,那么为什么我不能在 THEN
子句中使用它。我该怎么做才能得到我想要的结果。
我想要的查询结果是这样的:Get from_location,to_location, tariff (based on case from another table)。我期望外部查询将其 FROM_LOCATION、TO_LOCATION 传递给 CASE ELSE THEN
中的内部 select 查询,并基于此返回关税值,这将是外部查询的第三列。我该怎么做才能实现这一目标。
select FROM_LOCATION, TO_LOCATION,
case when (
select tariff A_tariff where A_tariff.FROM_LOCATION = B_TARIFFS.FROM_LOCATION AND A_tariff.TO_LOCATION =
B_TARIFFS.TO_LOCATION AND TO_DATE(sysdate,'YYYY-MM-DD') between TO_DATE(from_date,'YYYY-MM-DD') and TO_DATE(to_date,'YYYY-MM-DD')
and rownum = 1
) = ''
then
(SELECT TARIFF FROM (
SELECT * FROM A_TARIFF WHERE TRIM(A_TARIFF.FROM_LOCATION) = TRIM(**FROM_LOCATION**) AND
TRIM(A_TARIFF.TO_LOCATION) = TRIM(**TO_LOCATION**) ORDER BY A_TARIFF.FROM_DATE DESC
) WHERE ROWNUM = 1)
else
(select tariff from A_tariff where A_tariff.FROM_LOCATION = B_TARIFFS.FROM_LOCATION AND A_tariff.TO_LOCATION =
B_TARIFFS.TO_LOCATION AND TO_DATE(sysdate,'YYYY-MM-DD') between TO_DATE(from_date,'YYYY-MM-DD') and TO_DATE(to_date,'YYYY-MM-DD')
and rownum = 1) end tariff
FROM B_TARIFFS
WHERE FROM_LOCATION LIKE '%ABC%' AND AREA_CODE = 'X' ORDER BY TARIFFS;
你的问题出在双重嵌套上。
你为什么不改变:
(SELECT TARIFF FROM (
SELECT * FROM A_TARIFF WHERE TRIM(A_TARIFF.FROM_LOCATION) = TRIM(**FROM_LOCATION**) AND
TRIM(A_TARIFF.TO_LOCATION) = TRIM(**TO_LOCATION**) ORDER BY A_TARIFF.FROM_DATE DESC
) WHERE ROWNUM = 1)
和
SELECT TARIFF FROM A_TARIFF WHERE TRIM(A_TARIFF.FROM_LOCATION) = TRIM(B_TARIFFS.FROM_LOCATION) AND
TRIM(A_TARIFF.TO_LOCATION) = TRIM(B_TARIFFS.TO_LOCATION) WHERE ROWNUM = 1
ORDER BY A_TARIFF.FROM_DATE DESC
如@alexandergs 所述,错误原因是子查询嵌套太深。但你有比这更大的问题。
在您的 when
子句中,您根据一些随机行做出决定,因为条件 rownum=1
没有排序。
else
子句也是如此。也不清楚这个 when (select ...) = ''
是什么意思——我怀疑你想展示一些不空的东西,
但目前的建设不提供这一点。您必须将查询重建为类似此处的内容:
select b.from_location, b.to_location, a.tariff, b.tariffs,
row_number() over (partition by b.from_location, b.to_location
order by a.from_date desc) rn
from b_tariffs b
left join a_tariff a
on a.from_location = b.from_location and a.to_location = b.to_location
and trunc(sysdate) between trunc(a.from_date) and trunc(a.to_date)
where b.from_location like '%ABC%' and b.area_code = 'X' order by b.tariffs;
...最终为 row_number() 添加更多代码 - 因此它会根据您的需要对行进行排序并获取 RN = 1 的行。