AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 340504
Accepted
T N
T N
Asked: 2024-06-26 01:10:30 +0800 CST2024-06-26 01:10:30 +0800 CST 2024-06-26 01:10:30 +0800 CST

“ROW_NUMBER() OVER(ORDER BY xml.node)”定义是否明确?

  • 772

(这更多的是一个文档问题,而不是行为问题。它已按照那里的建议从Stack overflow迁移过来。)

在研究另一个需要按原始元素顺序提取 XML 节点的问题的答案时,我遇到了几个答案(此处、此处和此处),它们使用了形式为的表达式ROW_NUMBER() OVER (ORDER BY xml.node),并断言或暗示分配的行号值将按 XML 文档顺序分配。

但是,我找不到任何定义 行为的地方ORDER BY xml.node。尽管子句中似乎允许这样做OVER(),但文档并未具体提及 XML 节点。

例如,给定:

DECLARE @xml XML = '<root>
<node>One</node>
<node>Two</node>
<node>Three</node>
<node>Four</node>
</root>'

SELECT
    ROW_NUMBER() OVER(ORDER BY xml.node) AS rn,
    xml.node.value('./text()[1]', 'varchar(255)') AS value
FROM @xml.nodes('*/node') xml(node)
ORDER BY
    ROW_NUMBER() OVER(ORDER BY xml.node)

返回结果如下:

rn | value
----------
1  | One
2  | Two
3  | Three
4  | Four

问题:文档中是否有任何地方保证这些结果?这是否被接受为有保证但未记录的行为?或者这是否是另一种情况,ORDER BY (SELECT NULL)对于看似预先排序的小型源数据集似乎有效,但最终在扩大规模时可能会失败?我之所以问这个问题,是因为我宁愿不推荐使用其行为和可靠性不受文档支持的技术。

有趣的是,尽管 XML 节点可以在 windowed 中使用ORDER BY,但在普通的 中却不允许SELECT ... ORDER BY。在普通的 select order-by 子句中使用时,ORDER BY xml.node会产生以下错误:

消息 493 级别 16 状态 1 第 7 行

从 nodes() 方法返回的列“node”不能直接使用。它只能与四种 XML 数据类型方法(exist()、nodes()、query() 和 value())之一一起使用,或者在 IS NULL 和 IS NOT NULL 检查中使用。

上述错误消息没有列出窗口函数OVER(ORDER BY ...)作为允许的用途。

参见这个 db<>fiddle。

sql-server
  • 1 1 个回答
  • 705 Views

1 个回答

  • Voted
  1. Best Answer
    Paul White
    2024-06-26T07:34:54+08:002024-06-26T07:34:54+08:00

    不,没有记录,因此无法保证。

    实际上,它可能如我在Stack Overflow 答案(如下所示)中所述得到保证,但这并不能满足您对官方文档的渴望。

    您可以通过打开文档问题来要求他们记录此事。

    我个人会使用它,因为证据对我来说是可以接受的,但如果您也这样做,我不会赔偿您的损失。


    我的 Stack Overflow 答案

    无法在执行计划中明确看到它,但id该方法返回的列nodes()是varbinary(900) OrdPath,它确实封装了原始 xml 文档 order。

    Mikael Eriksson 针对相关问题该方法是否保持文档顺序?提供的解决方案依赖于OrdPath来提供一个必要的子句,以确定如何为 分配标识值。nodes()ORDER BYINSERT

    稍微更紧凑的用法如下:

    CREATE TABLE #T 
    (
        ID integer IDENTITY, 
        Fruit nvarchar(10) NOT NULL
    );
    
    DECLARE @xml xml = 
        N'
        <Fruits>
          <Apple />
          <Banana />
          <Orange />
          <Pear />
        </Fruits>
        ';
    
    INSERT #T 
        (Fruit)
    SELECT 
        N.n.value('local-name(.)', 'nvarchar(10)') 
    FROM @xml.nodes('/Fruits/*') AS N (n)
    ORDER BY
        ROW_NUMBER() OVER (ORDER BY N.n);
    
    SELECT 
        T.ID, 
        T.Fruit 
    FROM #T AS T
    ORDER BY
        T.ID;
    

    db<>小提琴

    目前还没有记录以这种方式使用OrdPath,但该技术在原则上是合理的:

    1. OrdPath反映文档顺序。
    2. 计算ROW_NUMBER按OrdPath * 排序的序列值。
    3. 该ORDER BY子句使用行号序列。
    4. 标识值按照 分配给行ORDER BY。

    需要明确的是,即使采用并行性,这也适用。正如 Mikael 所说,可疑的方面是使用,id因为ROW_NUMBER没有id记录为OrdPath。


    * 计划中未显示顺序,但使用 TF 8607 的优化器输出包含:

    ScaOp_SeqFunc row_number order[CALC:QCOL: XML Reader with XPath filter.id ASC]
    
    • 10

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve