为什么 newid() 在查询的最后实现? [英] Why does newid() materialize at the very end of a query?

查看:31
本文介绍了为什么 newid() 在查询的最后实现?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果您在 SQL Server 中运行以下示例代码,您会注意到 newid() 在联接之后具体化,而 row_number() 在联接之前具体化.有没有人理解这一点,是否有办法解决这个问题?

If you run the following sample code in SQL Server, you'll notice that newid() materializes after the join whereas row_number() materializes before the join. Does anyone understand this and if there's a way to work around it?

declare @a table ( num varchar(10) )
 insert into @a values ('dan')
 insert into @a values ('dan')
 insert into @a values ('fran')
 insert into @a values ('fran')

 select *
   from @a T
            inner join
        (select num, newid() id
           from @a
          group by num) T1      on T1.num = T.num         

 select *
   from @a T
            inner join
        (select num, row_number() over (order by num) id
           from @a
          group by num) T1      on T1.num = T.num

推荐答案

我不确定这里有什么问题.先具体化子查询T1:

Not sure I see what the problem is here. Materialize the subquery T1 first:

SELECT num, ROW_NUMBER() OVER (ORDER BY num) 
    FROM @a
    GROUP BY num;

你得到两行:

dan  1
fran 2

现在将它与 num = num 上的 a 连接起来,您将得到 4 行,每个不同的值对应 2 行.你在这里的实际目标是什么?也许你应该在外面申请 ROW_NUMBER() ?

Now join that against a on num = num, you get 4 rows, 2 for each distinct value. What is your actual goal here? Perhaps you should be applying ROW_NUMBER() outside?

具体化的顺序由优化器决定.您会发现其他内置函数(RAND()、GETDATE() 等)具有类似的不一致的实现行为.您对此无能为力,而且他们修复"它的机会也不大.

The order of materialization is up to the optimizer. You'll find that other built-ins (RAND(), GETDATE() etc.) have similarly inconsistent materialization behavior. Not much you can do about it, and not much chance they're going to "fix" it.

编辑

新的代码示例.将@a 的内容写入 #temp 表,以具体化"每个唯一 num 值的 NEWID() 分配.

New code sample. Write the contents of @a to a #temp table to "materialize" the NEWID() assignment per unique num value.

SELECT num, id = NEWID() 
  INTO #foo FROM @a GROUP BY num;

SELECT a.num, f.id 
  FROM @a AS a 
  INNER JOIN #foo AS f 
  ON a.num = f.num;

DROP TABLE #foo;

这篇关于为什么 newid() 在查询的最后实现?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆