Tsql 为什么newid()会在查询的最后具体化?

Tsql 为什么newid()会在查询的最后具体化?,tsql,sql-server-2008,Tsql,Sql Server 2008,如果在SQL Server中运行以下示例代码,您会注意到newid()在联接之后具体化,而row_number()在联接之前具体化。有人明白这一点吗?有没有办法解决这个问题 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')

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

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:

SELECT num, ROW_NUMBER() OVER (ORDER BY num) 
    FROM @a
    GROUP BY num;
您将得到两行:

dan  1
fran 2
现在将其与on num=num合并,得到4行,每个不同的值对应2行。你在这里的实际目标是什么?也许您应该在外部应用行号()

具体化的顺序取决于优化器。您会发现其他内置(RAND()、GETDATE()等)具有类似的不一致的物化行为。你对此无能为力,他们“修复”它的可能性也不大

编辑

新代码示例。将@a的内容写入#temp表,以“具体化”每个唯一num值的NEWID()赋值

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;

我不知道这里有什么问题。首先具体化子查询T1:

SELECT num, ROW_NUMBER() OVER (ORDER BY num) 
    FROM @a
    GROUP BY num;
您将得到两行:

dan  1
fran 2
现在将其与on num=num合并,得到4行,每个不同的值对应2行。你在这里的实际目标是什么?也许您应该在外部应用行号()

具体化的顺序取决于优化器。您会发现其他内置(RAND()、GETDATE()等)具有类似的不一致的物化行为。你对此无能为力,他们“修复”它的可能性也不大

编辑

新代码示例。将@a的内容写入#temp表,以“具体化”每个唯一num值的NEWID()赋值

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;

我有一个类似的问题,并发现“内部连接”是问题所在。我能够使用“左连接”…

我有一个类似的问题,并发现“内部连接”就是问题所在。我可以使用“左连接”。

@pst:那是因为它是“匿名的”。:-)@pst:那是因为它是“匿名的”。:-)这就是它对
row\u number()
的工作原理,但是看看它对
newid()
的工作原理。基本上,您需要编写什么才能使
newid()
row\u number()
一样工作?我不知道您可以,似乎newid()在查询中的任何位置都是具体化的。为什么不在插入行时创建GUID并防止重复?对于不同的num值,真正具体化NEWID()的唯一方法是首先将它们写下来。我将添加第二个代码示例。是的,不幸的是,在我的情况下,临时表效率低下。这很奇怪,但我认为这没有解决办法。我会接受你的,因为你可能是对的,这是我们能得到的最接近的。这就是它对
行数()的工作原理,但是看看它对
newid()的工作原理。
。基本上,您需要编写什么才能使
newid()
row\u number()
一样工作?我不知道您可以,似乎newid()在查询中的任何位置都是具体化的。为什么不在插入行时创建GUID并防止重复?对于不同的num值,真正具体化NEWID()的唯一方法是首先将它们写下来。我将添加第二个代码示例。是的,不幸的是,在我的情况下,临时表效率低下。这很奇怪,但我认为这没有解决办法。我接受你的观点,因为你可能是对的,这是我们能得到的最接近的结果。你能发表两个声明来证明你的观点吗?如果我是对的,你是说左联合将使newid()更快实现?听起来不太对。不幸的是,这里也不能选择左连接。你能发布两条语句来证明你的断言吗?如果我是对的,你是说左联合将使newid()更快实现?听起来不太对。不幸的是,这里也不能选择左连接。