2015-06-21 103 views
0

以下查詢嵌套子查詢中選擇記錄給我無效的標識符錯誤(a.id),因爲它裏面嵌套子查詢:使用ROWNUM在Oracle中導致無效的標識符錯誤

SELECT a.*, 
CASE WHEN 
SELECT id FROM (SELECT id, ROWNUM rnum FROM US b WHERE b.id = a.id ORDER BY b.createdate ASC) WHERE rnum = 2) = 21 THEN ‘Found’ 
END SEARCH 
FROM EU a 
JOIN US b ON b.id = a.id; 

任何人都可以給我建議另一種方法?

回答

1

你沒有描述你的設置或你想達到什麼,但這會解決嗎?

SQL Fiddle

的Oracle 11g R2架構設置

CREATE TABLE EU (id) AS 
SELECT 19+LEVEL 
FROM DUAL CONNECT BY LEVEL <= 5; 

CREATE TABLE US (id, createdate) AS 
SELECT 19+LEVEL, SYSDATE - LEVEL 
FROM DUAL CONNECT BY LEVEL <= 5 
UNION ALL 
SELECT 19+2*LEVEL, SYSDATE-LEVEL-5 
FROM DUAL CONNECT BY LEVEL <= 3; 

查詢1

SELECT a.*, 
     CASE WHEN a.id = 21 
      AND ROW_NUMBER() OVER (PARTITION BY a.id ORDER BY b.createdate) = 2 
      THEN 'Found' 
      END AS SEARCH 
FROM EU a 
JOIN US b 
ON  b.id = a.id 

Results

| ID | SEARCH | 
|----|--------| 
| 20 | (null) | 
| 21 | (null) | 
| 21 | Found | 
| 22 | (null) | 
| 23 | (null) | 
| 23 | (null) | 
| 24 | (null) | 
0

您的查詢的一個問題是在第二個SELECT之前沒有paren。我仍然認爲它不會起作用,因爲Oracle將標識符的範圍限制在一層以內。但是,這是我認爲你打算:

SELECT a.*, 
     (CASE WHEN (SELECT id 
        FROM (SELECT id, ROWNUM as rnum 
         FROM US b 
         WHERE b.id = a.id 
         ORDER BY b.createdate ASC 
         ) 
        WHERE rnum = 2 
       ) = 21 THEN ‘Found’ 
     END) SEARCH 
FROM EU a JOIN 
    US b 
    ON b.id = a.id; 

最簡單的方式得到你想要的是使用row_number():因爲id用於一切

select a.*, 
     (case when b.id = 21 then 'Found' end) as Search 
from eu a left join 
    (select b.*, 
      row_number() over (partition by b.id order by b.createddate) as seqnum 
     from us b 
    ) b 
    on b.id = a.id 
where seqnum = 2; 

查詢似乎很奇怪。您好像在查找ID爲21的兩條記錄。