在WHERE中引用ROW_NUMBER()

时间:2017-05-01 18:08:43

标签: sql sql-server function where row-number

查询结果超过500K。我想要做的是将这些分成100K的结果。我创建了一个行号列来帮助解决这个问题,但现在我在 WHERE 中引用了它,它将不会处理该函数并继续收到此错误:

消息4108,级别15,状态1,第1行 窗口函数只能出现在SELECT或ORDER BY子句中。

查询参考:

1  SELECT
2  mt.Name,
3  mt.IDNO,
4  so.IDType,
5  Row   =  ROW_NUMBER()OVER(ORDER BY mt.Name)
6
7  FROM         MainTable       mt WITH(NOLOCK)
8  LEFT JOIN    SupportTable1   so WITH(NOLOCK) ON  so.Name    = mt.Name
9  LEFT JOIN    SupportTable2   st WITH(NOLOCK) ON  st.Name    = mt.Name
10
11 WHERE    1=1
12 AND      ROW_NUMBER()OVER(ORDER BY mt.Name) BETWEEN '1' and '100000'
Msg 4108, Level 15, State 1, Line 12 Windowed functions can only
appear in the SELECT or ORDER BY clauses.

我可以做些什么来使用这个或者还有其他选择来探索可以给我我需要的东西吗?

感谢。

2 个答案:

答案 0 :(得分:3)

您没有使用MySQL。为此,请使用CTE或子查询:

SELECT s.*
FROM (SELECT mt.Name, mt.IDNO, so.IDType, Row = ROW_NUMBER() OVER (ORDER BY mt.Name)
      FROM MainTable mt LEFT JOIN
           SupportTable1 so 
           ON so.Name = mt.Name LEFT JOIN
           SupportTable2 st
           ON  st.Name = mt.Name
     ) s
WHERE Row BETWEEN 1 and 100000;

注意:

  • 不能在WHERE子句中使用窗口函数。
  • 列别名也不能在WHERE子句中使用;这就是需要CTE或子查询的原因。
  • 不要在整数常量周围加上单引号。

或者,您可以使用TOP

      SELECT TOP (100000) mt.Name, mt.IDNO, so.IDType, Row = ROW_NUMBER() OVER (ORDER BY mt.Name)
      FROM MainTable mt LEFT JOIN
           SupportTable1 so 
           ON so.Name = mt.Name LEFT JOIN
           SupportTable2 st
           ON  st.Name = mt.Name
      ORDER BY Row;

答案 1 :(得分:0)

从Sql Server 2012开始,OFFSET和FETCH NEXT被添加到ORDER BY子句中。

SELECT mt.Name, mt.IDNO, so.IDType
FROM MainTable mt WITH(NOLOCK)
LEFT JOIN SupportTable1 so WITH(NOLOCK) ON so.Name = mt.Name
LEFT JOIN SupportTable2 st WITH(NOLOCK) ON st.Name = mt.Name
ORDER BY mt.Name OFFSET 0 ROWS FETCH NEXT 100000 ROWS ONLY;

然后在每次新迭代时向OFFSET编号添加100000。