web-dev-qa-db-fra.com

Ajouter une colonne d'identité à une vue dans SQL Server 2008

Voici mon point de vue:

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

J'ai besoin d'ajouter une nouvelle colonne nommée Id et j'ai besoin que cette colonne soit unique, je pense donc ajouter une nouvelle colonne comme identité. Je dois mentionner que cette vue a renvoyé une grande quantité de données, j'ai donc besoin d'un moyen avec de bonnes performances, et j'utilise également deux requêtes de sélection avec union, je pense que cela pourrait être compliqué, alors quelle est votre suggestion?

14
Saeid

Utilisez la fonction ROW_NUMBER() dans SQL Server 2008.

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
25
Daniel P

La vue est juste une requête stockée qui ne contient pas les données elles-mêmes, vous pouvez donc ajouter un ID stable. Si vous avez besoin d'un identifiant à d'autres fins comme la pagination par exemple, vous pouvez faire quelque chose comme ceci:

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
)
3
Diego

Il n'y a aucune garantie que les lignes renvoyées par une requête utilisant ROW_NUMBER () seront ordonnées exactement de la même manière à chaque exécution, sauf si les conditions suivantes sont remplies:

  1. Les valeurs de la colonne partitionnée sont uniques. [les partitions sont parent-enfant, comme un patron a 3 employés] [ignorer]
  2. Les valeurs des colonnes ORDER BY sont uniques. [si la colonne 1 est unique, row_number doit être stable]
  3. Les combinaisons de valeurs de la colonne de partition et des colonnes ORDER BY sont uniques. [si vous avez besoin de 10 colonnes dans votre commande pour devenir unique ... allez-y pour rendre row_number stable] "

Il y a un problème secondaire ici, avec ce point de vue. Les By Order ne fonctionnent pas toujours dans les vues (bug sql de longue date). Ignorer le row_number () pendant une seconde:

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
)
2
Rich

L'utilisation de "row_number () sur (ordre par col1) comme ID" est très coûteuse. Cette façon est beaucoup plus efficace en termes de coût:

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
)
0
klingu