如何一次加载特定行100

时间:2014-05-20 12:27:27

标签: sql sql-server sql-server-2008

我正在尝试搜索每100个记录,因此第一个批量将是1到100秒将是101到200等。
我也使用连接来组合两个表 当我执行查询时,我收到错误消息:The column 'ID' was specified multiple times for 'cte'.

这是我的疑问:

WITH cte AS (
    SELECT
          ROW_NUMBER() OVER (
            ORDER BY TableOne.Name
          ) AS ROW
        , *
    FROM
      DatabaseNameOne
      FULL JOIN DatabaseNameOne
      ON DatabaseNameTwo.ID= DatabaseNameOne.ID
    WHERE CONVERT(DATE,DatabaseNameOne.dateone) BETWEEN '2013-12-01' AND '2014-05-20'
)

SELECT
    *
FROM
    cte
WHERE
    ROW BETWEEN '1' AND '100'

有人可以告诉我这里我做错了吗?

我正在使用服务器2008.我可以选择1到100条记录而不加入,但是当我加入表格时,我收到此错误

4 个答案:

答案 0 :(得分:3)

这是你的cte:

WITH cte AS (
       SELECT ROW_NUMBER() OVER(ORDER BY TableOne.Name) AS ROW,
              *
       FROM DatabaseNameOne FULL JOIN
            DatabaseNameOne
            ON DatabaseNameTwo.ID = DatabaseNameOne .ID
       WHERE convert(date, DatabaseNameOne.dateone) between '2013-12-01' and '2014-05-20'
     )

您正在将表连接到自身并使用* - 所有列都是重复的。即使表格不同,join也位于ID字段上,因此该列将被复制。 CTE /子查询/表不能有重复的名称? SQL Server如何知道您在引用中引用哪个列?

相反,您需要从join列出所需的特定列。

答案 1 :(得分:2)

我假设您打算加入DatabaseNameTwo并且每个表都有三个字段。 如果展开select *:

,您当前的cte正在做什么
WITH cte AS (
    SELECT
          ROW_NUMBER() OVER (
            ORDER BY TableOne.Name
          ) AS ROW
        , DatabaseNameOne.id,  DatabaseNameOne.SomeOtherField,  DatabaseNameOne.YetAnotherField, 
         DatabaseNameTwo.id, DatabaseNameTwo.AnotherField,  DatabaseNameTwo.HowManyMoreFieldsAreThere
   FROM
      DatabaseNameOne
      FULL JOIN DatabaseNameOne
      ON DatabaseNameTwo.ID= DatabaseNameOne.ID
    WHERE CONVERT(DATE,DatabaseNameOne.dateone) BETWEEN '2013-12-01' AND '2014-05-20'
)

如您所见,有两列名称ID。这就是错误的错误。

由于两个ID都相同,因此您只需列出一个(您应该永远不会使用select *的众多原因之一是重复加入时浪费宝贵数据库和网络资源的数据)。所以这应该工作(在更改为真正的列名和表名并修复最终查询中的select *后,我太懒了):

WITH cte AS (
    SELECT
          ROW_NUMBER() OVER (
            ORDER BY TableOne.Name
          ) AS ROW
        , DatabaseNameOne.id,  DatabaseNameOne.SomeOtherField,  DatabaseNameOne.YetAnotherField, 
         DatabaseNameTwo.AnotherField,  DatabaseNameTwo.HowManyMoreFieldsAreThere
   FROM
      DatabaseNameOne
      FULL JOIN DatabaseNameOne
      ON DatabaseNameTwo.ID= DatabaseNameOne.ID
    WHERE CONVERT(DATE,DatabaseNameOne.dateone) BETWEEN '2013-12-01' AND '2014-05-20'
)

SELECT
    <List the fies here)
FROM
    cte
WHERE
    ROW BETWEEN '1' AND '100'

答案 2 :(得分:0)

我猜Row是一个整数,你尝试将其作为varchar()

试试这个

    WITH cte AS (
SELECT ROW_NUMBER() OVER(ORDER BY TableOne.Name
) 
    AS ROW,* 
FROM DatabaseNameOne JOIN DatabaseNameOne ON DatabaseNameTwo .ID= DatabaseNameOne .ID

WHERE convert(date,DatabaseNameOne .dateone) between '2013-12-01' and '2014-05-20')

SELECT * FROM cte WHERE ROW BETWEEN 1 AND 100 --not '1' and '100'

答案 3 :(得分:0)

很难想象什么是TableOne?是架构名称吗?如果它是表格或首字母缩略词,您可以在表格实名后添加它。接下来是我们没有DatabaseNameTwo的定义,但是它出现在连接条件上。

即使它的拼写错误和cte在真实脚本中使用了正确的表名,也无法使用两个连接表中的相同列名。据我所知,两个表都包含ID列,在那里使用SELECT *是不可接受的。也许使用DatabaseNameOne。*或DatabaseNameTwo。*可能有帮助吗?

但即使在那里,最好确定查询使用的确切列名,只是为了最小化内存使用,I / O活动等。