Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Criar uma coluna computada que usa dados de outra tabela no SQL Server


Uma limitação amplamente conhecida das colunas computadas no SQL Server é que elas não podem acessar dados de outras tabelas. Ou seja, sua expressão pode usar colunas na mesma tabela, mas não em outras tabelas.

Mas isso é apenas meia verdade. Embora você não possa referenciar a coluna de outra tabela diretamente em sua expressão, você pode invocar uma função definida pelo usuário. E, portanto, você pode criar uma função definida pelo usuário que executa o cálculo que você precisa e, em seguida, basta chamar essa função como a expressão da sua coluna computada.

Aqui está um exemplo para demonstrar.


Tabelas de amostra


Tenho um banco de dados com as seguintes tabelas:
SELECT TOP(5) * FROM Artists;

+------------+------------------+--------------+-------------+
| ArtistId   | ArtistName       | ActiveFrom   | CountryId   |
|------------+------------------+--------------+-------------|
| 1          | Iron Maiden      | 1975-12-25   | 3           |
| 2          | AC/DC            | 1973-01-11   | 2           |
| 3          | Allan Holdsworth | 1969-01-01   | 3           |
| 4          | Buddy Rich       | 1919-01-01   | 6           |
| 5          | Devin Townsend   | 1993-01-01   | 8           |
+------------+------------------+--------------+-------------+


SELECT TOP(5) * FROM Albums;

+-----------+------------------------+---------------+------------+-----------+
| AlbumId   | AlbumName              | ReleaseDate   | ArtistId   | GenreId   |
|-----------+------------------------+---------------+------------+-----------|
| 1         | Powerslave             | 1984-09-03    | 1          | 1         |
| 2         | Powerage               | 1978-05-05    | 2          | 1         |
| 3         | Singing Down the Lane  | 1956-01-01    | 6          | 3         |
| 4         | Ziltoid the Omniscient | 2007-05-21    | 5          | 1         |
| 5         | Casualties of Cool     | 2014-05-14    | 5          | 1         |
+-----------+------------------------+---------------+------------+-----------+

Essas tabelas, na verdade, contêm mais de 5 linhas. Selecionei as 5 principais linhas para que você tenha uma visão geral dos dados e da estrutura da tabela.

Agora, imagine que eu queira adicionar uma coluna computada à primeira tabela.

Quero que a coluna computada forneça o número de álbuns de cada artista. Em outras palavras, preciso contar os álbuns na outra tabela - os Albums tabela.

Visto que os dados estão em outra tabela, não posso referenciá-los diretamente de dentro de uma coluna computada. Mas posso criar uma função definida pelo usuário e fazer referência a essa função de dentro da minha coluna computada.

Criar a função


Aqui está uma função simples que conta o número de álbuns de um determinado artista:
CREATE FUNCTION [dbo].[ufn_AlbumCount] (@ArtistId int)  
RETURNS smallint
AS  
BEGIN  
    DECLARE @AlbumCount int;
    SELECT @AlbumCount = COUNT(AlbumId)
    FROM Albums
    WHERE ArtistId = @ArtistId; 
    RETURN @AlbumCount;
END;
GO

Criar a coluna computada


Agora que criei a função, posso adicionar uma coluna computada que a referencia.
ALTER TABLE Artists
ADD AlbumCount AS dbo.ufn_AlbumCount(ArtistId);

Testar a coluna calculada


Agora posso executar uma consulta nos Artists table para ver o resultado da minha coluna computada:
SELECT TOP(10) * FROM Artists;

Resultado:
+------------+------------------+--------------+-------------+--------------+
| ArtistId   | ArtistName       | ActiveFrom   | CountryId   | AlbumCount   |
|------------+------------------+--------------+-------------+--------------|
| 1          | Iron Maiden      | 1975-12-25   | 3           | 5            |
| 2          | AC/DC            | 1973-01-11   | 2           | 3            |
| 3          | Allan Holdsworth | 1969-01-01   | 3           | 2            |
| 4          | Buddy Rich       | 1919-01-01   | 6           | 1            |
| 5          | Devin Townsend   | 1993-01-01   | 8           | 3            |
| 6          | Jim Reeves       | 1948-01-01   | 6           | 1            |
| 7          | Tom Jones        | 1963-01-01   | 4           | 3            |
| 8          | Maroon 5         | 1994-01-01   | 6           | 0            |
| 9          | The Script       | 2001-01-01   | 5           | 1            |
| 10         | Lit              | 1988-06-26   | 6           | 0            |
+------------+------------------+--------------+-------------+--------------+

Indexação


Você só pode usar a coluna computada em um índice se a função definida pelo usuário que ela invoca tiver os seguintes valores de propriedade:
  • ÉDeterminístico =verdadeiro
  • IsSystemVerified =true (a menos que a coluna computada persista)
  • UserDataAccess =falso
  • SystemDataAccess =falso