加入两个值为null的表

时间:2012-08-18 20:20:24

标签: sql sql-server join

我的表格Visit包含VisitIDPatientIDDoctorID等列以及PrescriptionID列。表Prescription中有列PrescriptionIDDrugID(它们是我的主键)。一个处方可以有很多药物,所以会有类似的东西:

处方ID:1药物ID:38
处方ID:1药物ID:278
处方ID:1药物ID:7

Visit表中,将插入“1”值作为PrescriptionID。但是现在我不能用外键加入这两个表,因为不是每次访问都有处方,所以PrescriptionID可以为null,我有错误,列必须是主键或必须是唯一的。我怎样才能以另一种方式加入这些表?

3 个答案:

答案 0 :(得分:2)

你似乎在谈论两个不同的问题。

一个问题是,您希望在引用列中允许空值。这很简单,您只需要将列定义为可为空的作为外键。该密钥应该引用的是另一个问题,它将我们引向您在问题中可以看到的两个问题中的另一个。

有关列必须是主键或唯一的错误与引用表使用单个列引用复合(由两列组成)键的事实有关。并且您不能仅引用密钥的一部分,因为引用必须是特定的单个行,并且您的Visit.PrescriptionID值可能引用多个(并且正确如此,因为引用表中的行不是处方,而是处方项。这就是为什么你被告知列必须是主键或唯一。

因此,我建议您更改架构如下:

  1. 让您的Prescription表仅包含处方作为实体。即使没有其他属性而不是密钥,也要将其存储在自己的表中:

    CREATE TABLE Presciption (
      PrescriptionID int
        IDENTITY  /* just an assumption */
        CONSTRAINT PK_Prescription PRIMARY KEY
    );
    
  2. 您的现有Prescription表应根据您的单数名词命名约定重命名为PrescriptionItemPrescriptionDrug。它的PrescriptionID列将是引用Prescription.PrescriptionID的外键,如下所示:

    CREATE TABLE PresciptionDrug (
      PrescriptionID int NOT NULL
        CONSTRAINT FK_PrescriptionDrug_Prescription
        FOREIGN KEY REFERENCING Prescription (PrescriptionID),
      DrugID int NOT NULL
        CONSTRAINT FK_PrescriptionDrug_Drug
        FOREIGN KEY REFERENCING Drug (DrugID),
      CONSTRAINT PK_PrescriptionDrug
        PRIMARY KEY (PrescriptionID, DrugID)
    );
    
  3. 现在您可以在Visit.PrescriptionID上定义外部内容,如下所示:

    ALTER TABLE Visit
    ADD CONSTRAINT FK_Visit_Prescription
        FOREIGN KEY REFERENCING Prescription (PrescriptionID)
    ;
    

    如果您想为访问选择处方,请不要忘记确保该列可以为空。 (可以在SQL Server中使用可以为空的外键。)

答案 1 :(得分:1)

我认为表结构应该是

Visit (VisitID, Time, .....) --no prescriptionID
Prescription (PrescriptionID, ..... , VisitID) --VisitID as FK
PrescriptionDrugs(PrescriptionID, DrugID) -- Both columns as PK

然后你的查询将是

SELECT v.VisitID FROM Visit v
LEFT JOIN Prescription p ON v.VisitID = p.VisitID
LEFT JOIN PrescriptionDrugs pd ON p.PrescriptionID = pd.PrescriptionID

这会给你类似的东西

VisitID        PrescriptionID      DrugID
101            ABC                 Anti-Bio
101            ABC                 Asprin
102            BAC                 Anti-Bio

含义Visit 101的2种药物和Visit 102

的1种药物

无论如何,使用您当前的架构,试试这个

select v.visitid, v.presid, p.drugid 
from visit v 
left join prescription p on v.presid = p.presid

答案 2 :(得分:0)

你在问怎么做:

select *
  from Visit as V left outer join
    Prescription as P on P.PrescriptionId = V.PrescriptionId

这将返回所有访问和任何适用的处方。没有处方的访问将导致没有处方数据的输出行。