如何从2个表中选择所有连接的行,包括null

时间:2015-01-08 13:29:30

标签: mysql sql select join left-join

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

疫苗接种基本上是在疫苗接种类型和患者之间加入多对多表。它有3个属性:vaccine_id,registration_no和date。 Vaccination_type有vaccine_id,疫苗名称。

我想加入这两个表并获取这些条目:

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

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

3 个答案:

答案 0 :(得分:2)

如果您想要一次注册的信息,那么这应该是您的基表。那么你想获得该注册的所有疫苗接种类型。最后加入疫苗接种表以获得它的管理日期,如果该人从未得到它,则为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

小提琴:http://sqlfiddle.com/#!2/e8b2d/5

答案 1 :(得分:0)

使用 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;

答案 2 :(得分:0)

正如我现在理解的那样,您需要列出所有接种疫苗,您需要看到所有患者(或特定患者),以了解患者接种和未接种的疫苗。是的,这是可能的,但它需要所有三个表。 Vaccination_Type表具有所有疫苗接种的列表,患者表具有所有患者的列表。疫苗接种表中列出了患者接种的疫苗。

第一步是为所有患者创建所有疫苗接种的笛卡尔积。这将为您提供所有疫苗接种的清单,并为每个疫苗接种提供所有患者的清单。

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

然后左边连接现有的交叉表。

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   vaccine_id, registration_no, vaccination_date
from     All_Vaccinations
where    registration_no = 1111;

然而,如果特定患者的疫苗接种历史记录大部分都是您想要的,那么只需两张表就可以获得更好的表现:

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不在选择列表之外,因为我们不再使用Patients表。我们本可以使用Vaccinations表中的registration_no字段,但如果患者缺少疫苗接种,不仅日期字段而且结果集的registration_no字段将包含NULL。没有理由公开A)你已经知道的值和B)在某些行中具有适当值而在其他行中具有NULL的字段。这可能会导致一些混乱。当您一次查看多个患者的数据时,必须使用三表联接,因为需要registration_no才能理解输出。