ROW_NUMBER和多个JOIN

时间:2014-04-21 16:34:29

标签: sql sql-server

当我测试此请求时:

SELECT 
    *, ROW_NUMBER() OVER (ORDER BY test1) AS lineNumb 
FROM 
    (SELECT DISTINCT 
        tab1.test1, tab2.test2
     FROM TB_tab1 tab1
     JOIN TB_tab2 tab2 ON tab2.test3 = tab1.test3 
     JOIN TB_tab3 tab3 ON tab3.test4 = tab1.test4 
     WHERE tab3.test5 != 'test') AS sub
WHERE lineNumb BETWEEN 1 AND 5

我明白了:

  

错误:列名无效:'lineNumb'。 SQLState:S0001 ErrorCode:207

为什么以及如何更正我的要求?

4 个答案:

答案 0 :(得分:1)

SELECT *
FROM 
(
SELECT *, ROW_NUMBER() OVER (ORDER BY test1) AS lineNumb FROM (
SELECT DISTINCT tab1.test1, tab2.test2
FROM TB_tab1 tab1
JOIN TB_tab2 tab2 ON tab2.test3 = tab1.test3 
JOIN TB_tab3 tab3 ON tab3.test4 = tab1.test4 WHERE tab3.test5 !='test') as sub
) as sub2 
WHERE lineNumb BETWEEN 1 AND 5

答案 1 :(得分:1)

为什么:

您无法访问select的where子句中的别名lineNumb列 - 它不会在上下文中定义。

如何纠正:

使用您拥有的子查询或CTE,并使用您的位置从中选择。

SELECT * 
  FROM (<you existing query without the where>)
 WHERE lineNumb <= 5

答案 2 :(得分:1)

您无法在同一级别的where中使用列别名。您可以使用分析功能执行所需操作。您甚至不需要distinct

SELECT *
FROM (SELECT tab1.test1, tab2.test2,
             ROW_NUMBER() OVER (PARTITION BY tab1.test1, tab2.test2 ORDER BY test1) as seqnum,
             DENSE_RANK() OVER (ORDER BY test1) as lineNumb
      FROM TB_tab1 tab1
      JOIN TB_tab2 tab2 ON tab2.test3 = tab1.test3 
      JOIN TB_tab3 tab3 ON tab3.test4 = tab1.test4
      WHERE tab3.test5 <> 'test'
     ) sub
WHERE lineNumb BETWEEN 1 AND 5 AND seqnum = 1;

答案 3 :(得分:1)

在这个问题中查看SELECT语句中的执行顺序:

What's the execute order of the different parts of a SQL select statement?

直到执行语句后才能读取SELECT子句。因此,在进入ORDER BY子句之前,不能引用别名。