为 union 中的组创建唯一标识符
Create a unique identifier for groups from union
有没有办法为每个要动态生成的[群组]获取唯一ID?我试过 newid() 但结果是每行的值不同。目的是不必担心为每个 T 集添加唯一值(如注释掉的集所示)。 ([Value] 的每个值(例如 1)的初始字符对应于 [Group] 的硬编码值,仅用于查看结果时的可读性目的。)
select
[Name],
[Value],
[Group]
from (
select
[Name],
[Value],
1 as [Group] --newid() as [Group] --
from (
values
('abc', '1qwert'),
('def', '1yuiop')
) as T ([Name], [Value])
union all
select
[Name],
[Value],
2 as [Group] --newid() as [Group] --
from (
values
('abc', '2asdfg'),
('def', '2hjkl')
) as T ([Name], [Value])
union all
select
[Name],
[Value],
3 as [Group] --newid() as [Group] --
from (
values
('abc', '3zxcv'),
('def', '3bnm')
) as T ([Name], [Value])
--union all
--select
-- [Name],
-- [Value],
-- ? as [Group] --newid() as [Group] --
--from (
-- values
-- ('abc', '?poiuy'),
-- ('def', '?trewq')
-- ) as T ([Name], [Value])
) as TT
order by
[Group],
[Name];
一般来说,函数 NEWID() 为每一行生成唯一值,当我们将它作为列放在 select 列表中时:
select
NEWID() as column_name
from table
函数的奇怪行为存在一个众所周知的常见问题 NEWID()。
所以我们实际上不能强制查询优化器从子句中实现 NEWID() 值:
select
t.*,
t2.col
from table t
cross join (select NEWID() as col) t2
在这种情况下,我们再次为每一行获得相同的唯一值。
仍然,我们必须找到一种方法来强制优化器计算 from 子句中的 NEWID() 值。
正如我们从 logical query processing 命令中知道的那样,"ORDER" 运算符几乎在查询结束时执行,在 SELECT 子句之后。在我们想要对它们进行排序之前,我们必须知道值。
所以首先,我们应该按 NEWID() 值以某种方式对查询中的 "select" 语句进行排序。
这样做的唯一合法可能性是添加 TOP 1 运算符。
其次,为了确保优化器不会因为只有 1 个值而跳过排序,我们添加了另一个 NEWID() 值。
因此,对于每个联合 select 我们应该添加:
cross join (select top 1 t.group_id from (values (NEWID()), (NEWID()))as t(group_id) ORDER BY group_id) as tt
在这种情况下,无论如何,优化器都应该对它应该事先知道的值进行排序。
查询如下所示:
select
[Name],
[Value],
[Group]
from (
select
[Name],
[Value],
tt.group_id as [Group]
from (
values
('abc', '1qwert'),
('def', '1yuiop')
) as T ([Name], [Value])
cross join (select top 1 t.group_id from (values (NEWID()), (NEWID()))as t(group_id) ORDER BY group_id) as tt
union all
select
[Name],
[Value],
tt.group_id as [Group]
from (
values
('abc', '2asdfg'),
('def', '2hjkl')
) as T ([Name], [Value])
cross join (select top 1 t.group_id from (values (NEWID()), (NEWID()))as t(group_id) ORDER BY group_id) as tt
union all
select
[Name],
[Value],
tt.group_id as [Group]
from (
values
('abc', '3zxcv'),
('def', '3bnm')
) as T ([Name], [Value])
cross join (select top 1 t.group_id from (values (NEWID()), (NEWID()))as t(group_id) ORDER BY group_id) as tt
) as t
在这种情况下,我们不应该在 table.
中具体化随机唯一值
最后的更正是添加
select top 1 t.group_id from (values (NEWID()), (NEWID()))as t(group_id) ORDER BY group_id
进入 CTE。
最终查询将如下所示:
;with unique_group as (
select top 1
t.group_id
from (values
(NEWID()),
(NEWID())
)as t(group_id)
order by group_id
)
select
[Name],
[Value],
[Group]
from (
select
[Name],
[Value],
tt.group_id as [Group]
from (
values
('abc', '1qwert'),
('def', '1yuiop')
) as T ([Name], [Value])
cross join unique_group as tt
union all
select
[Name],
[Value],
tt.group_id as [Group]
from (
values
('abc', '2asdfg'),
('def', '2hjkl')
) as T ([Name], [Value])
cross join unique_group as tt
union all
select
[Name],
[Value],
tt.group_id as [Group]
from (
values
('abc', '3zxcv'),
('def', '3bnm')
) as T ([Name], [Value])
cross join unique_group as tt
) as t
为联合中的每个子查询提供一个唯一的参考编号,将该编号与一小组 newid() 值相关联,这些值也共享同一组整数。
;with cte as (
select 1 as gid, newid() as [group]
union all
select gid + 1, newid()
from cte
where gid < 3
)
select
[Name],[Value],[Group]
from (
select
[Name],[Value], 1 as gid
from (
values
('abc', '1qwert'),
('def', '1yuiop')
) as T ([Name], [Value])
union all
select
[Name],[Value], 2 as gid
from (
values
('abc', '2asdfg'),
('def', '2hjkl')
) as T ([Name], [Value])
union all
select
[Name], [Value], 3 as gid
from (
values
('abc', '3zxcv'),
('def', '3bnm')
) as T ([Name], [Value])
) d
inner join cte on d.gid = cte.gid
参见:https://rextester.com/IEPJC57700
+----+------+--------+--------------------------------------+
| | Name | Value | Group |
+----+------+--------+--------------------------------------+
| 1 | abc | 1qwert | 68f1884f-c3af-44b6-9856-2ca71615e4aa |
| 2 | def | 1yuiop | 68f1884f-c3af-44b6-9856-2ca71615e4aa |
| 3 | abc | 2asdfg | bf36a235-ef68-4c02-a502-8ba0009aa302 |
| 4 | def | 2hjkl | bf36a235-ef68-4c02-a502-8ba0009aa302 |
| 5 | abc | 3zxcv | 221ca4d2-ed7f-4654-9234-7081360f693c |
| 6 | def | 3bnm | 221ca4d2-ed7f-4654-9234-7081360f693c |
+----+------+--------+--------------------------------------+
有没有办法为每个要动态生成的[群组]获取唯一ID?我试过 newid() 但结果是每行的值不同。目的是不必担心为每个 T 集添加唯一值(如注释掉的集所示)。 ([Value] 的每个值(例如 1)的初始字符对应于 [Group] 的硬编码值,仅用于查看结果时的可读性目的。)
select
[Name],
[Value],
[Group]
from (
select
[Name],
[Value],
1 as [Group] --newid() as [Group] --
from (
values
('abc', '1qwert'),
('def', '1yuiop')
) as T ([Name], [Value])
union all
select
[Name],
[Value],
2 as [Group] --newid() as [Group] --
from (
values
('abc', '2asdfg'),
('def', '2hjkl')
) as T ([Name], [Value])
union all
select
[Name],
[Value],
3 as [Group] --newid() as [Group] --
from (
values
('abc', '3zxcv'),
('def', '3bnm')
) as T ([Name], [Value])
--union all
--select
-- [Name],
-- [Value],
-- ? as [Group] --newid() as [Group] --
--from (
-- values
-- ('abc', '?poiuy'),
-- ('def', '?trewq')
-- ) as T ([Name], [Value])
) as TT
order by
[Group],
[Name];
一般来说,函数 NEWID() 为每一行生成唯一值,当我们将它作为列放在 select 列表中时:
select
NEWID() as column_name
from table
函数的奇怪行为存在一个众所周知的常见问题 NEWID()。 所以我们实际上不能强制查询优化器从子句中实现 NEWID() 值:
select
t.*,
t2.col
from table t
cross join (select NEWID() as col) t2
在这种情况下,我们再次为每一行获得相同的唯一值。
仍然,我们必须找到一种方法来强制优化器计算 from 子句中的 NEWID() 值。 正如我们从 logical query processing 命令中知道的那样,"ORDER" 运算符几乎在查询结束时执行,在 SELECT 子句之后。在我们想要对它们进行排序之前,我们必须知道值。
所以首先,我们应该按 NEWID() 值以某种方式对查询中的 "select" 语句进行排序。 这样做的唯一合法可能性是添加 TOP 1 运算符。
其次,为了确保优化器不会因为只有 1 个值而跳过排序,我们添加了另一个 NEWID() 值。
因此,对于每个联合 select 我们应该添加:
cross join (select top 1 t.group_id from (values (NEWID()), (NEWID()))as t(group_id) ORDER BY group_id) as tt
在这种情况下,无论如何,优化器都应该对它应该事先知道的值进行排序。
查询如下所示:
select
[Name],
[Value],
[Group]
from (
select
[Name],
[Value],
tt.group_id as [Group]
from (
values
('abc', '1qwert'),
('def', '1yuiop')
) as T ([Name], [Value])
cross join (select top 1 t.group_id from (values (NEWID()), (NEWID()))as t(group_id) ORDER BY group_id) as tt
union all
select
[Name],
[Value],
tt.group_id as [Group]
from (
values
('abc', '2asdfg'),
('def', '2hjkl')
) as T ([Name], [Value])
cross join (select top 1 t.group_id from (values (NEWID()), (NEWID()))as t(group_id) ORDER BY group_id) as tt
union all
select
[Name],
[Value],
tt.group_id as [Group]
from (
values
('abc', '3zxcv'),
('def', '3bnm')
) as T ([Name], [Value])
cross join (select top 1 t.group_id from (values (NEWID()), (NEWID()))as t(group_id) ORDER BY group_id) as tt
) as t
在这种情况下,我们不应该在 table.
中具体化随机唯一值最后的更正是添加
select top 1 t.group_id from (values (NEWID()), (NEWID()))as t(group_id) ORDER BY group_id
进入 CTE。
最终查询将如下所示:
;with unique_group as (
select top 1
t.group_id
from (values
(NEWID()),
(NEWID())
)as t(group_id)
order by group_id
)
select
[Name],
[Value],
[Group]
from (
select
[Name],
[Value],
tt.group_id as [Group]
from (
values
('abc', '1qwert'),
('def', '1yuiop')
) as T ([Name], [Value])
cross join unique_group as tt
union all
select
[Name],
[Value],
tt.group_id as [Group]
from (
values
('abc', '2asdfg'),
('def', '2hjkl')
) as T ([Name], [Value])
cross join unique_group as tt
union all
select
[Name],
[Value],
tt.group_id as [Group]
from (
values
('abc', '3zxcv'),
('def', '3bnm')
) as T ([Name], [Value])
cross join unique_group as tt
) as t
为联合中的每个子查询提供一个唯一的参考编号,将该编号与一小组 newid() 值相关联,这些值也共享同一组整数。
;with cte as (
select 1 as gid, newid() as [group]
union all
select gid + 1, newid()
from cte
where gid < 3
)
select
[Name],[Value],[Group]
from (
select
[Name],[Value], 1 as gid
from (
values
('abc', '1qwert'),
('def', '1yuiop')
) as T ([Name], [Value])
union all
select
[Name],[Value], 2 as gid
from (
values
('abc', '2asdfg'),
('def', '2hjkl')
) as T ([Name], [Value])
union all
select
[Name], [Value], 3 as gid
from (
values
('abc', '3zxcv'),
('def', '3bnm')
) as T ([Name], [Value])
) d
inner join cte on d.gid = cte.gid
参见:https://rextester.com/IEPJC57700
+----+------+--------+--------------------------------------+
| | Name | Value | Group |
+----+------+--------+--------------------------------------+
| 1 | abc | 1qwert | 68f1884f-c3af-44b6-9856-2ca71615e4aa |
| 2 | def | 1yuiop | 68f1884f-c3af-44b6-9856-2ca71615e4aa |
| 3 | abc | 2asdfg | bf36a235-ef68-4c02-a502-8ba0009aa302 |
| 4 | def | 2hjkl | bf36a235-ef68-4c02-a502-8ba0009aa302 |
| 5 | abc | 3zxcv | 221ca4d2-ed7f-4654-9234-7081360f693c |
| 6 | def | 3bnm | 221ca4d2-ed7f-4654-9234-7081360f693c |
+----+------+--------+--------------------------------------+