在 WHERE 中引用 ROW_NUMBER()

Referencing ROW_NUMBER() in WHERE

查询产生超过 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.

我该怎么做才能使用它,或者是否有其他可供探索的选项可以满足我的需求?

谢谢。

您没有使用 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;

备注:

  • Window 函数不能用在 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;

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

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;

然后在每次新迭代时将 100000 添加到 OFFSET 数字。