NESTED SELECT QUERY WITH CASE

时间:2015-06-02 14:39:40

标签: sql oracle select subquery case

请查看查询。
我面临的问题是:
THEN子句中的 FROM_LOCATION TO_LOCATION 需要是B_TARIFFS的值,但是当我在B_TARIFFS.FROM_LOCATIONB_TARIFFS.TO_LOCATION前面添加前缀时,我得到的是错误ORA-00904: Invalid identifier.。 如果它在ELSE子句中可用,那么为什么我不能在THEN子句中使用它。我该怎么做才能得到我想要的结果。
我想从查询得到的结果是:获取from_location,to_location,tariff(基于另一个表的大小写)。我期望外部查询将其FROM_LOCATION,TO_LOCATION传递给CASE ELSE THEN中的内部选择查询,并且基于此将返回将成为外部查询的第三列的资费值。我能做些什么来实现这一目标。

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;

2 个答案:

答案 0 :(得分:1)

你的问题在于双重嵌套。

你为什么不改变:

    (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 

答案 1 :(得分:1)

正如@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的行。