在TSQL中用Newid()值替换Dense_Rank()值吗?

时间:2018-07-25 14:46:09

标签: tsql

在TSQL中是否可以用Newid()值替换Dense_Rank()生成的值?我使用Dense_Rank()进行分组,但是我需要生成一个uniqueidentifier而不是一个整数。预先感谢。

1 个答案:

答案 0 :(得分:1)

没有直接的方法来执行此操作,但是正如我在评论中提到的那样,您可以为每个记录获取dense_rank(),然后为每个不同的NEWID()生成一个Dense_Rank(),然后重新加入自身。

CREATE TABLE test(f1 int, f2 char(1));
INSERT INTO test 
VALUES (1, 'a'),
  (1, 'b'),
  (1, 'c'),
  (2, 'a'),
  (2, 'b'),
  (3, 'a'),
  (3, 'd'),
  (3, 'g');

With dr AS (SELECT f1, f2, dense_rank() OVER (PARTITION BY f1 ORDER BY f2) as dr FROM test)
,dr_newid AS (SELECT dr, newid() as nid FROM (SELECT dr FROM dr GROUP BY dr) as drsub)
SELECT dr.f1, dr.f2, dr.dr, dr_newid.nid
FROM dr LEFT OUTER JOIN dr_newid ON dr.dr = dr_newid.dr
ORDER BY f1, f2;

+----+----+----+--------------------------------------+
| f1 | f2 | dr |                 nid                  |
+----+----+----+--------------------------------------+
|  1 | a  |  1 | 966389AF-4C70-4AA8-A5C9-6F9537B8A1B8 |
|  1 | b  |  2 | 73BE2978-B7D7-46B8-8B04-3103C8410575 |
|  1 | c  |  3 | CB935CCA-AFE5-4D13-9583-0440DF1BEFE2 |
|  2 | a  |  1 | 966389AF-4C70-4AA8-A5C9-6F9537B8A1B8 |
|  2 | b  |  2 | 73BE2978-B7D7-46B8-8B04-3103C8410575 |
|  3 | a  |  1 | 966389AF-4C70-4AA8-A5C9-6F9537B8A1B8 |
|  3 | d  |  2 | 73BE2978-B7D7-46B8-8B04-3103C8410575 |
|  3 | g  |  3 | CB935CCA-AFE5-4D13-9583-0440DF1BEFE2 |
+----+----+----+--------------------------------------+

请注意,根据您的盒子如何执行从drdr_newid的联接,可能会为每个不同的density_rank值生成唯一的newid。使用LEFT JOIN应该诱使优化器生成dr_newid中间结果集,然后再将其结合起来。 INNER JOIN可能不会。

如果给出的结果不正确,则可以将dr_newid转储到临时表中,然后再加入,从而迫使服务器为每个不同的dense_rank()派生一次newid(),并避免使用强制优化器逻辑的技巧

sqlfiddle here