【问题标题】:How to load specific rows 100 at a time如何一次加载特定行 100
【发布时间】:2014-05-20 12:27:27
【问题描述】:

我正在尝试搜索每 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 条记录而不加入,但是一旦我加入一个表,我就会收到这个错误

【问题讨论】:

  • 你对错误信息的解释是什么?
  • @DanBracuk 你是什么意思?
  • 我的意思是错误信息非常具体。你读过它还是只是注意到你有一个?
  • "DatabaseNameOne FULL JOIN DatabaseNameOne" -> 应该是某个地方的“Two”?

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


【解决方案1】:

这是你的 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 中列出您想要的特定列。

【讨论】:

  • 我认为“同一张表”位可能只是一个匿名故障,因为他们随后在 ON 子句中使用了 DatabaseNameTwo 别名。
  • 我收到错误 ')' 附近的语法不正确。加上我在哪里指定记录数? Uswing 其他人的建议我尝试添加列名,我得到同样的错误
  • 这只是 cte,不是完整的查询。
【解决方案2】:

我将假设您打算加入 DatabaseNameTwo,并且每个表都有三个字段。 如果您展开选择 *,您当前的 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'

【讨论】:

    【解决方案3】:

    我猜 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'
    

    【讨论】:

    • 虽然将整数常量放在单引号中是不好的形式,但 SQL Server 会在整数上下文中将字符串转换为整数。
    • 我收到同样的错误消息The column 'ID' was specified multiple times for 'cte'.
    • @User911: 如下所述指定列名而不是* 然后SELECT * FROM cte WHERE ROW BETWEEN 1 AND 100
    • @861051069712110711711710997114 这就是我所做的select TableOne.Name from cte where ....
    【解决方案4】:

    很难想象 TableOne 是什么?它是模式名称吗?如果是表格或缩写,可以在表格实名后加上。接下来是我们没有 DatabaseNameTwo 的定义,但它存在于连接条件中。

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

    但即便如此,最好还是确定查询使用的确切列名,以尽量减少内存使用量、i/o 活动等。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-29
      相关资源
      最近更新 更多