sql >> Base de Datos >  >> RDS >> Sqlserver

Cree una columna calculada que use datos de otra tabla en SQL Server

Una limitación ampliamente conocida de las columnas calculadas en SQL Server es que no pueden acceder a los datos de otras tablas. Es decir, su expresión puede usar columnas en la misma tabla, pero no de otras tablas.

Pero esto es sólo una verdad a medias. Si bien no puede hacer referencia a la columna de otra tabla directamente dentro de su expresión, puede invocar una función definida por el usuario. Y, por lo tanto, podría crear una función definida por el usuario que realice el cálculo que necesita, luego simplemente llame a esa función como la expresión de su columna calculada.

Aquí hay un ejemplo para demostrarlo.

Tablas de muestra

Tengo una base de datos con las siguientes tablas:

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         |
+-----------+------------------------+---------------+------------+-----------+

Estas tablas en realidad contienen más de 5 filas. He seleccionado las 5 filas superiores para que pueda obtener una imagen de los datos y la estructura de la tabla.

Ahora, imagina que quiero agregar una columna calculada a la primera tabla.

Quiero que la columna calculada proporcione la cantidad de álbumes de cada artista. En otras palabras, lo necesito para contar los álbumes en la otra tabla:Albums mesa.

Dado que los datos están en otra tabla, no puedo hacer referencia a ellos directamente desde una columna calculada. Pero puedo crear una función definida por el usuario en su lugar y hacer referencia a esa función desde mi columna calculada.

Crear la función

Aquí hay una función simple que cuenta la cantidad de álbumes de un artista determinado:

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

Crear la columna calculada

Ahora que he creado la función, puedo agregar una columna calculada que haga referencia a ella.

ALTER TABLE Artists
ADD AlbumCount AS dbo.ufn_AlbumCount(ArtistId);

Probar la columna calculada

Ahora puedo ejecutar una consulta contra los Artists table para ver el resultado de mi columna calculada:

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            |
+------------+------------------+--------------+-------------+--------------+

Indización

Solo puede usar la columna calculada en un índice si la función definida por el usuario que invoca tiene los siguientes valores de propiedad:

  • EsDeterminista =verdadero
  • IsSystemVerified =verdadero (a menos que la columna calculada se mantenga)
  • Acceso a datos de usuario =falso
  • Acceso a datos del sistema =falso