2017-09-24 6 views
1

J'utilise concepteur de requêtes SQL Server pour essayer de former une requête externe qui renverra le nom et l'adresse de chaque assuré aux politiques d'accueil et celles sans politiques. Mes créer déclarations sont les suivantes:SQL jointure externe - Joindre nécessite 3 tables

CREATE TABLE Address (
    AddressID integer NOT NULL, 
    HouseNumber Integer NOT NULL, 
    Street varchar(20) NOT NULL, 
    CityCounty varchar(20) NOT NULL, 
    StateAbb char(2), 
    CountryAbb char(2) NOT NULL, 
    Zip char(5) NOT NULL, 
    LastUpdatedBy varchar(20) NOT NULL, 
    LastUpdated date NOT NULL, 
    CONSTRAINT PK_Address PRIMARY KEY (AddressID)); 

    CREATE TABLE Insured(
    InsuredID integer NOT NULL, 
    FirstName varchar(15) NOT NULL, 
    LastName varchar(15) NOT NULL, 
    MI char(1), 
    DateOfBirth date NOT NULL, 
    CreditScore integer NOT NULL, 
    AddressID integer NOT NULL, 
    DriversLicenseNumber varchar(35), 
    LastUpdatedBy varchar(20) NOT NULL, 
    LastUpdated date NOT NULL, 
    CONSTRAINT PK_Insured PRIMARY KEY (InsuredID), 
    CONSTRAINT FK_InsuredAddress FOREIGN KEY (AddressID) references Address); 

    CREATE TABLE Policy(
    PolicyID integer NOT NULL, 
    EffectiveDate date NOT NULL, 
    TerminationDate date NOT NULL, 
    Amount Numeric (8,2) NOT NULL, 
    PolicyYear integer NOT NULL, 
    PolicyType char(1) NOT NULL, 
    InsuredID integer NOT NULL, 
    AddressID integer NOT NULL, 
    LastUpdatedBy varchar(20) NOT NULL, 
    LastUpdated date NOT NULL, 
    CONSTRAINT PK_Policy PRIMARY KEY (PolicyID), 
    CONSTRAINT FK_PolicyAddress FOREIGN KEY (AddressID) references Address, 
    CONSTRAINT FK_PolicyInsured FOREIGN KEY (InsuredID) references Insured); 

    CREATE TABLE Home(
    PolicyID integer NOT NULL, 
    ExteriorType varchar(30) NOT NULL, 
    Alarm char(3) NOT NULL, 
    DistanceToFireStation integer NOT NULL, 
    LastUpdatedBy varchar(20) NOT NULL, 
    LastUpdated date NOT NULL, 
    CONSTRAINT PK_Home PRIMARY KEY (PolicyID), 
    CONSTRAINT FK_HomePolicy FOREIGN KEY (PolicyID) references Policy); 

    CREATE TABLE Auto(
    PolicyID integer NOT NULL, 
    VinNumber varchar(30) NOT NULL, 
    Make varchar(15) NOT NULL, 
    Model varchar(20) NOT NULL, 
    MilesPerYear integer NOT NULL, 
    LastUpdatedBy varchar(20) NOT NULL, 
    LastUpdated date NOT NULL, 
    CONSTRAINT PK_Auto PRIMARY KEY (PolicyID), 
    CONSTRAINT FK_AutoPolicy FOREIGN KEY (PolicyID) references Policy); 

Je crois que la requête nécessite des tables adresse, assuré, politique et un droit externe ou à gauche rejoindre, mais je ne peux pas obtenir le serveur SQL pour reconnaître qu'il en conserve la formation d'une jointure interne et jointure croisée. De quoi ai-je besoin pour une requête qui renvoie les assurés avec des polices d'assurance habitation et leurs adresses et assurés sans police ni adresse?

Ce que j'ai essayé jusqu'à présent:

SELECT Insured.InsuredID, Insured.FirstName, 
     Insured.LastName, Address.HouseNumber, 
     Policy.PolicyID 
FROM Address RIGHT JOIN Policy 
ON Address.AddressID = Policy.AddressID 
RIGHT JOIN Insured ON Policy.AddressID = Insured.AddressID 
ORDER BY Insured.InsuredID 

Ceci est la dernière requête qui renvoie ce que je dois pour les assurés avec une politique de la maison, mais pour les assurés sans une politique que je reçois des valeurs NULL dans l'adresse.

SELECT i.InsuredID, i.FirstName, i.MI, i.LastName,    
a.HouseNumber, a.Street, a.CityCounty, a.StateAbb, a.CountryAbb, a.Zip 
FROM INSURED i 
LEFT JOIN (SELECT * FROM Policy WHERE PolicyType = 'H') HomePolicy on  
i.InsuredID = HomePolicy.InsuredID 
LEFT JOIN Address a on HomePolicy.AddressID = a.AddressID; 
+0

Montrez-nous votre travail. – nicomp

+0

Le plus proche que j'ai obtenu: SELECT Insured.InsuredID, Insured.FirstName, Insured.LastName, Address.HouseNumber, Policy.PolicyID Adresse DE RIGHT JOIN Politique sur Address.AddressID = Policy.AddressID RIGHT JOIN ON Assuré Policy.AddressID = Insured.AddressID ORDER BY Insured.InsuredID; – nammrick

+0

Je vais ajouter à votre question initiale - s'il vous plaît faire à l'avenir –

Répondre

0

Pourriez-vous essayer cette requête:

SELECT i.InsuredID, 
i.FirstName, 
i.LastName, 
a.HouseNumber, 
p.PolicyID 
FROM insured i 
LEFT JOIN policy p ON i.AddressID = p.AddressID AND p.PolicyType = 'H' 
LEFT JOIN address a ON i.AddressID = a.AddressID 
ORDER BY i.InsuredID; 

Je pense que les jointures étaient dans le mauvais ordre. Cela vous donne-t-il ce dont vous avez besoin? Mise à jour: L'association de la table Assured à la table Address affiche les adresses, qu'elles aient ou non une stratégie.

+0

j'ai changé ce que vous avez publié un peu et son retour assurés par une politique de la maison, mais pour les assurés sans politique leur adresse est renvoyée comme nul donc je suis certainement se rapprocher . – nammrick

+0

Ah, j'ai compris. J'ai changé la jointure un peu, est-ce maintenant OK? – bbrumm

+0

C'est certainement encore plus proche.Le seul problème est maintenant que la requête retourne tous les assurés (politique de la maison, politique automobile, pas de politique) non seulement les assurés avec une politique de la maison et les assurés sans une politique. – nammrick

0

La conception de base de données semble bonne. Je pense que nous avons des doutes mineurs concernant la colonne "PolicyType". quelle valeur elle détient et quel est le but de cette colonne.

Dites PolicyType='H' cela signifie que c'est la politique de la maison. Ou un autre moyen de trouver la même requête est de vérifier si ce policyid existe dans la table home.

Est-ce correct?

requête principale,

Que dois-je besoin d'une requête qui retourne avec les politiques assurés à domicile et leurs adresses et sans politique assurés et leurs adresses?

Vérifiez ce script,

--insureds with home policies and their addresses 
select i.InsuredID, 
i.FirstName, 
i.LastName 
A.HouseNumber 
,1 INDICATE 
from Insured i 
INNER JOIN policy p ON i.InsuredID = p.InsuredID 
INNER JOIN [Address] A ON A.ADDRESSID=I.ADDRESSID 
WHERE EXISTS(SELECT PolicyID FROM Home H WHERE h.PolicyID=P.PolicyID) 
AND NOT EXISTS(SELECT PolicyID FROM [Auto] a WHERE A.PolicyID=P.PolicyID) 

UNION ALL 
--insureds with no policy and their addresses 
select i.InsuredID, 
i.FirstName, 
i.LastName 
,A.HouseNumber 
,0 INDICATE 
from Insured i 
INNER JOIN [Address] A ON A.ADDRESSID=I.ADDRESSID 
WHERE EXISTS(SELECT InsuredID FROM policy p WHERE i.InsuredID = p.InsuredID) 

je utiliser "toute clause" parce que la colonne de la table est nécessite pas dans votre sortie.