SQL telling me a column I created is not found

Dom 941 Reputation points
2023-07-04T21:58:44.6033333+00:00

I'm sure I'm missing something in the syntax, but I'm just not seeing it. If I just created the column rn why is it an invalid column?

select 
	   [PlanID]
      ,[SubSystemId]
       ,[Cat3]
	  ,[factor]
	  ,[ValidFrom]
      ,row_number() 
	  
	  over(partition by 	  
	  [PlanID]
      ,[SubSystemId]
      ,[Cat3]
	  
	  order by [ValidFrom] desc) as rn

	  from DB.[dbo].[sometable] as T
	  where
rn = 1      

Msg 207, Level 16, State 1, Line 20
Invalid column name 'rn'.

SQL Server | Other
0 comments No comments
{count} votes

3 answers

Sort by: Most helpful
  1. Erland Sommarskog 121.9K Reputation points MVP Volunteer Moderator
    2023-07-04T22:06:51.3366667+00:00

    A SELECT query is logically evaluated in this order: FROM-JOIN-WHERE-GROUP BY-HAVING-SELECT-ORDER BY. Thus, something you define in the SELECT list cannot be used in the WHERE clause. (But it can be used in ORDER BY).

    The way to resolve this issue is to use nested queries. This is often done with Common Table Expressions (CTE). For instance:

    ; WITH numbering AS (
       select [PlanID]
             ,[SubSystemId]
              ,[Cat3]
    	     ,[factor]
    	     ,[ValidFrom]
             ,row_number()  over(partition by [PlanID], [SubSystemId] ,[Cat3]
                                 order by [ValidFrom] desc) as rn
    	from DB.[dbo].[sometable] as T
    )
    SELECT * 
    FROM   numbering 
    WHERE  rn = 1
    
    0 comments No comments

  2. Bruce (SqlWork.com) 78,006 Reputation points Volunteer Moderator
    2023-07-04T22:15:43.67+00:00

    rn is a column alias in the result set and not valid in the where clause.

    you can use a with:

    with T as (
      select 
    	   [PlanID]
          ,[SubSystemId]
           ,[Cat3]
    	  ,[factor]
    	  ,[ValidFrom]
          ,row_number() over(partition by 	  
    	        [PlanID]
               ,[SubSystemId]
               ,[Cat3]
    	       order by [ValidFrom] desc) as rn
       from DB.[dbo].[sometable]
    ) 
    
    select *
    from T
    where rn = 1;      
    
    

    or use a derived table:

    select *
    from (select 
    	   [PlanID]
          ,[SubSystemId]
           ,[Cat3]
    	  ,[factor]
    	  ,[ValidFrom]
          ,row_number() 	  
    	  over(partition by 	  
       	     [PlanID]
            ,[SubSystemId]
            ,[Cat3]
    	    order by [ValidFrom] desc) as rn
       from DB.[dbo].[sometable]
    ) as T
    where rn = 1;    
    
    0 comments No comments

  3. LiHongMSFT-4306 31,571 Reputation points
    2023-07-05T01:04:26.4266667+00:00

    Hi @Dom

    Msg 207, Level 16, State 1, Line 20 Invalid column name 'rn'.

    As experts answered above, it is caused by the logical processing steps. The alias you specified in Select (Step5) cannot be used in Where (Step 2).

    You could also find workarounds in above answers.

    If any answer helps on your issue, you could mark it as answer so other user with similar problem could see this easier. :)

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.