如何 select 来自 2 个表的所有连接行,包括 null

How to select all joined rows from 2 tables including null

我目前有 2 个 table,疫苗接种和 vaccination_type 可以使用 vaccine_id 属性加入。

疫苗接种基本上是 vaccination_type 和患者之间的多对多 table 连接。它有 3 个属性:vaccine_id、registration_no 和日期。 Vaccination_type 有 vaccine_id、vaccine_name。

我想加入这 2 个 table 并获得这些条目:

vaccine_id vaccine_name registration_no date
1          influenza    1111            2015-01-15
2          hepatitis B  null            null
3          polio        1111            2015-01-15
4          hepatitis A  1112            2015-01-15

这意味着即使患者没有接种乙肝疫苗,我仍然希望该条目为空。但我只想要特定的 registration_no,在本例中为 1111,换句话说,我也希望甲型肝炎写为空,因为 1111 没有完成。所以如果我正在处理,我的预期结果1111 将是:

vaccine_id vaccine_name registration_no date
1          influenza    1111            2015-01-15
2          hepatitis B  null            null
3          polio        1111            2015-01-15
4          hepatitis A  null            null

我试过使用所有的连接,但找不到完美的连接。任何建议将不胜感激,谢谢!

使用 LEFT JOIN 它连接两个表。

试试这个:

SELECT VT.vaccine_id, VT.vaccine_name, V.registration_no
FROM Vaccination_type VT 
LEFT JOIN vaccination V ON VT.vaccine_id = V.vaccine_id;

如果您想要一次注册的信息,那么那应该是您的基地 table。然后您想获得该注册的所有疫苗接种类型。最后加入疫苗接种 table 以获得接种日期,如果该人从未接种疫苗则为 NULL:

SELECT
  registrations.registration_no,
  vaccination_type.vaccine_id,
  vaccination_type.name,
  vaccination.date
FROM
  registrations
  CROSS JOIN vaccination_type
  LEFT JOIN vaccination ON registrations.registration_no = vaccination.registration_no AND vaccination_type.vaccine_id = vaccination.vaccine_id
WHERE
  registrations.registration_no = 1111

Fiddle: http://sqlfiddle.com/#!2/e8b2d/5

正如我现在理解的问题,您需要一份所有疫苗接种的清单,您需要查看所有患者(或特定患者)以了解患者接种了哪些疫苗和未接种哪些疫苗。是的,这是可能的,但它需要所有三个 table。 Vaccination_Type table 包含所有疫苗接种的列表,Patients table 包含所有患者的列表。疫苗接种 table 列出了患者接种的疫苗。

第一步是创建所有患者的所有疫苗接种的笛卡尔积。这将为您提供所有疫苗接种的列表,以及每种疫苗接种的所有患者的列表。

select   vt.vaccine_id, p.registration_no
from     Vaccination_Type vt
cross join Patients       p;

然后向左加入现有的十字架 table。

select   vt.vaccine_id, p.registration_no, v.vaccination_date
from     Vaccination_Type vt
cross join Patients       p
left join Vaccinations    v
    on    v.vaccine_id = vt.vaccine_id
    and   v.registration_no = p.registration_no;

这为您提供了所有患者的所有疫苗接种。如果患者已接种疫苗,则后面会注明接种疫苗的日期。否则,日期字段将为 NULL。

如果这是您定期需要的东西,例如报告,您可以创建上述查询的视图,然后 select 来自该视图。

如果您只想查看与特定患者有关的此列表,您可以select从以下视图:

select   vaccine_id, registration_no, vaccination_date
from     All_Vaccinations
where    registration_no = 1111;

但是,如果某个特定患者的疫苗接种史主要是您想要的,您只需两次 table 即可获得,性能稍好一些:

select   vt.vaccine_id, v.vaccination_date
from     Vaccination_Type vt
left join Vaccinations    v
    on   v.vaccine_id = vt.vaccine_id
    and  v.registration_no = 1111;

请注意,registration_no 被排除在 select 列表之外,因为我们不再使用患者 table。我们本可以使用 Vaccinations table 中的 registration_no 字段,但是如果患者没有接种疫苗,结果集的日期字段和 registration_no 字段都将包含 NULL .没有理由公开 A) 您已经知道其值和 B) 在某些行中具有正确值而在其他行中具有 NULL 的字段。这可能会导致一些混乱。当您一次查看多个患者的数据时,您必须使用三 table 连接,因为需要 registration_no 才能理解输出。