Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Erstellen Sie eine berechnete Spalte, die Daten aus einer anderen Tabelle in SQL Server verwendet

Eine weithin bekannte Einschränkung von berechneten Spalten in SQL Server besteht darin, dass sie nicht auf Daten aus anderen Tabellen zugreifen können. Das heißt, Ihr Ausdruck kann Spalten in derselben Tabelle verwenden, aber nicht in anderen Tabellen.

Aber das ist nur die halbe Wahrheit. Sie können in Ihrem Ausdruck zwar nicht direkt auf die Spalte einer anderen Tabelle verweisen, aber Sie können eine benutzerdefinierte Funktion aufrufen. Daher könnten Sie eine benutzerdefinierte Funktion erstellen, die die erforderliche Berechnung durchführt, und diese Funktion dann einfach als Ausdruck Ihrer berechneten Spalte aufrufen.

Hier ist ein Beispiel zur Veranschaulichung.

Beispieltabellen

Ich habe eine Datenbank mit den folgenden Tabellen:

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

Diese Tabellen enthalten tatsächlich mehr als 5 Zeilen. Ich habe die obersten 5 Zeilen ausgewählt, damit Sie sich ein Bild von der Daten- und Tabellenstruktur machen können.

Stellen Sie sich nun vor, ich möchte der ersten Tabelle eine berechnete Spalte hinzufügen.

Ich möchte, dass die berechnete Spalte die Anzahl der Alben von jedem Künstler angibt. Mit anderen Worten, ich brauche es, um die Alben in der anderen Tabelle zu zählen – die Albums Tabelle.

Da sich die Daten in einer anderen Tabelle befinden, kann ich sie nicht direkt aus einer berechneten Spalte referenzieren. Aber ich kann stattdessen eine benutzerdefinierte Funktion erstellen und diese Funktion in meiner berechneten Spalte referenzieren.

Funktion erstellen

Hier ist eine einfache Funktion, die die Anzahl der Alben eines bestimmten Künstlers zählt:

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

Erstellen Sie die berechnete Spalte

Nachdem ich die Funktion erstellt habe, kann ich eine berechnete Spalte hinzufügen, die darauf verweist.

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

Testen Sie die berechnete Spalte

Jetzt kann ich eine Abfrage für die Artists ausführen Tabelle, um das Ergebnis meiner berechneten Spalte zu sehen:

SELECT TOP(10) * FROM Artists;

Ergebnis:

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

Indizierung

Sie können die berechnete Spalte nur in einem Index verwenden, wenn die benutzerdefinierte Funktion, die sie aufruft, die folgenden Eigenschaftswerte hat:

  • Ist deterministisch =wahr
  • IstSystemverifiziert =true (es sei denn, die berechnete Spalte wird beibehalten)
  • Benutzerdatenzugriff =falsch
  • Systemdatenzugriff =falsch