|
Priorität von verschiedenen Tabellenfeldern
Frage: Ich muss in meinem View ein Spaltenergebnis anzeigen, welches entweder den abgerechneten oder den vorbewerteten Wert ausgibt, wobei aber ein vorgefundener abgerechneter Wert eine Priorität gegenüber dem vorbewerteten Wert hat. Diese vorbewerteten/abgerechneten Werte sind über mehrere Datensätze verteilt. Wie wird so etwas umgesetzt?
Antwort: Wenn der MS SQL Server 2000 verwendet wird, kann diese Aufgabe über die COALESCE-Funktion in Verbindung mit einem LEFT JOIN umgesetzt werden. Das Ganze erklärt sich am Besten durch ein kleines Beispiel. Angenommen, zu einem Kunden kann die private ('H' wie Home) und die dienstliche ('B' wie Business) Telefonnummer separat gespeichert werden. Das folgende SQL-Script legt die über referenzielle Integrität verknüpften Beispieltabellen sowie einige Testdatensätze in der MS SQL Server-Datenbank tempdb an:
USE tempdb
GO
CREATE TABLE Customers (
CustNo INTEGER NOT NULL PRIMARY KEY,
LastName VARCHAR(10) NOT NULL,
FirstName VARCHAR(10) NOT NULL)
GO
INSERT INTO Customers VALUES (1,'Regel','Wolfgang')
INSERT INTO Customers VALUES (2,'Ritz','Bernd')
INSERT INTO Customers VALUES (3,'Lindner','Andreas')
GO
CREATE TABLE Telephones (
TelRecNo INTEGER NOT NULL PRIMARY KEY,
CustNo INTEGER NOT NULL REFERENCES Customers(CustNo),
TelType CHAR(1) NOT NULL CHECK(TelType IN ('H','B')),
TelNo INTEGER NOT NULL)
GO
INSERT INTO Telephones VALUES(1,1,'H',123)
INSERT INTO Telephones VALUES(2,1,'B',543)
INSERT INTO Telephones VALUES(3,2,'H',333)
INSERT INTO Telephones VALUES(4,3,'H',666)
INSERT INTO Telephones VALUES(5,3,'B',777)
GO
Eine Abfrage, bei der die Business-Telefonnummer gegenüber der Home-Telefonnummer bevorzugt wird, nutzt die COALESCE-Funktion. Diese Funktion gibt den ersten Ausdruck ohne NULL-Wert an die Argumente des Ausdrucks zurück, so dass ein Datensatz mit der Kennung 'B' für die dienstliche Telefonnummer bevorzugt wird. Nur dann, wenn keine dienstliche Telefonnummer vorgefunden wird, liefert die Abfrage in der gleichen Ergebnisspalte die private Telefonnummer zurück:
SELECT c.LastName, c.FirstName,
COALESCE(TB.TelNo, TH.TelNo) AS TelNo,
COALESCE(TB.TelType, TH.TelType) AS TelType
FROM Customers c
LEFT JOIN Telephones TB ON c.CustNo = TB.CustNo AND TB.TelType = 'B'
LEFT JOIN Telephones TH ON c.CustNo = TH.CustNo AND TH.TelType = 'H'
WHERE COALESCE(TB.TelNo, TH.TelNo) IS NOT NULL
Als Ergebnis erhält man in meinem Beispiel die folgende Auflistung:
LastName FirstName TelNo TelType
-------- --------- ----- -------
Regel Wolfgang 543 B
Ritz Bernd 333 H
Lindner Andreas 777 B
|