【问题标题】:Add Identity column to a view in SQL Server 2008将标识列添加到 SQL Server 2008 中的视图
【发布时间】:2012-05-10 01:41:12
【问题描述】:

这是我的看法:

Create View [MyView] as
(
Select col1, col2, col3 From Table1
UnionAll
Select col1, col2, col3 From Table2
)

我需要添加一个名为 Id 的新列,并且我需要此列是唯一的,所以我想添加新列作为标识。我必须提到这个视图返回了大量数据,所以我需要一种性能良好的方法,而且我使用两个 select 查询和 union all 我认为这可能有些复杂,你有什么建议?

【问题讨论】:

  • SQL Server 中的视图只是一个“存储查询”——它在数据库中没有任何物理表示。因此,您不能将标识列添加到视图中
  • id 不稳定是否可以(如果Table1 增长,Table2 的第一个id 将与以前不同)?
  • @marc_s - OP 可能只是在这里寻找 ROW_NUMBER 类型功能。
  • @marc_s - 没错,这就是为什么我问稳定的 ID 是否重要...
  • 如果您想要一个“稳定”的 id,这意味着对于视图中的每一行,您始终拥有相同的 id,您必须将 ID 存储在与保存该行的表相关的某个位置。视图不是您可以存储此类信息的地方,因此您需要一个表,或者您需要在用于构建视图的表中添加一列。

标签: sql sql-server sql-server-2008 tsql view


【解决方案1】:

将 ROW_NUMBER() 与“order by (select null)”一起使用,这样成本会更低,并且会得到您的结果。

Create View [MyView] as
SELECT ROW_NUMBER() over (order by (select null)) as id, *
FROM(
    Select col1, col2, col3 From Table1
    Union All
    Select col1, col2, col3 From Table2 ) R
GO

【讨论】:

  • ROW_NUMBER() 不会产生稳定的 ID。一旦基础数据发生变化,ID 就可能变得不一致。
【解决方案2】:

使用“row_number() over (order by col1) 作为 ID”非常昂贵。 这种方式在成本上效率更高:

Create View [MyView] as
(
    Select ID = isnull(cast(newid() as varchar(40)), '')
           , col1
           , col2
           , col3 
    From Table1
    UnionAll
    Select ID = isnull(cast(newid() as varchar(40)), '')
           , col1
           , col2
           , col3 
    From Table2
)

【讨论】:

  • 问题不谈row_number。这应该是对其他内容的评论吗?
  • 生成 GUID 也不是免费的。所以这取决于数据和订购的成本。
【解决方案3】:

除非满足以下条件,否则无法保证使用 ROW_NUMBER() 的查询返回的行在每次执行时的顺序完全相同:

  1. 分区列的值是唯一的。 [分区是父子,比如一个老板有3个员工][忽略]
  2. ORDER BY 列的值是唯一的。 [如果第 1 列是唯一的,row_number 应该是稳定的]
  3. 分区列和 ORDER BY 列的值组合是唯一的。 [如果您需要按顺序排列 10 列来获得唯一性...去使 row_number 稳定]"

这里有一个次要问题,这是一种观点。 Order By 并不总是在视图中工作(长期的 sql 错误)。暂时忽略 row_number():

create view MyView as 
(
    select top 10000000 [or top 99.9999999 Percent] col1 
    from  (
        Select col1 From Table1
        Union All
        Select col1 From Table2
    ) a order by col1
)

【讨论】:

  • 问题不谈row_number。这应该是对另一个答案或评论的评论吗?否则,这个答案缺少一些上下文/前提。这似乎不是问题的答案。
【解决方案4】:

视图只是一个不包含数据本身的存储查询,因此您可以添加一个稳定的 ID。如果您需要一个 id 用于其他目的,例如分页,您可以执行以下操作:

create view MyView as 
(
    select row_number() over ( order by col1) as ID, col1 from  (
        Select col1 From Table1
        Union All
        Select col1 From Table2
    ) a
)

【讨论】:

  • 是的,但这不会提供稳定的 id。
  • 是的,但他没有说他需要一个。我假设他需要 id 用于其他目的,例如分页
【解决方案5】:

在 SQL Server 2008 中使用 ROW_NUMBER() 函数。

Create View [MyView] as

SELECT ROW_NUMBER() OVER( ORDER BY col1 ) AS id, col1, col2, col3
FROM(
    Select col1, col2, col3 From Table1
    Union All
    Select col1, col2, col3 From Table2 ) AS MyResults
GO

【讨论】:

  • 是的,但这不会提供稳定的 id。
  • 如果您发布代码、XML 或数据示例,在文本编辑器中突出显示这些行,然后单击编辑器上的“代码示例”按钮 ({ })工具栏以很好地格式化和语法突出显示它!
  • 谢谢你。这对于在提交表之前测试视图中的数据非常有用。在我的情况下,只使用这样的通配符更方便:SELECT ROW_NUMBER() OVER (ORDER BY col1) as ID, x.* FROM (SELECT blah blah blah) as x
猜你喜欢
  • 2011-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-29
  • 1970-01-01
  • 1970-01-01
  • 2017-08-14
相关资源
最近更新 更多