MYSQL JOIN给出了意想不到的(但令人愉快的)结果?

ehi*_*ime 5 mysql join left-join

嘿伙计们,我正在摸着这个,我希望有人可以帮我解释一下.老实说,我有点害怕以后可能会咬我的屁股....

所以,我现在有三张桌子.reports,berriesmelons.我设置了这样的查询,它让我得到了我想要的东西.

SELECT 
   rpt.*, 
   ber.shipper, ber.po, ber.commodity, ber.label

FROM reports rpt

LEFT JOIN berries ber ON rpt.inspection_number = ber.report_key
LEFT JOIN melons mel ON rpt.inspection_number = mel.report_key

WHERE rpt.status='1'  OR rpt.status='0'
ORDER BY rpt.inspection_number DESC
Run Code Online (Sandbox Code Playgroud)

我得到了预期的回报

key | role | region   | inspection_type | inspection_number | shipper   | po    | commodity     | label
3   | NULL | Seattle  | melons          | 5555              | Shipper1  | PO2   | Commodity2    | Label2
2   | NULL | Seattle  | berries         | 1023              | Shipper1  | PO1   | Commodity1    | Label1
Run Code Online (Sandbox Code Playgroud)

如果我LEFT JOIN melons mel ON rpt.inspection_number = mel.report_key从我的陈述中删除我得到完全相同的东西......我从未提及过melons

如果我修改并使用JOIN浆果

SELECT 
   rpt.*, 
   ber.shipper, ber.po, ber.commodity, ber.label

FROM reports rpt

JOIN berries ber ON rpt.inspection_number = ber.report_key

WHERE rpt.status='1'  OR rpt.status='0'
ORDER BY rpt.inspection_number DESC
Run Code Online (Sandbox Code Playgroud)

它产生我所期望的应该!

key | role | region   | inspection_type | inspection_number | shipper   | po    | commodity     | label
2   | NULL | Seattle  | berries         | 1023              | Shipper1  | PO1   | Commodity1    | Label1
Run Code Online (Sandbox Code Playgroud)

但是试图像我这样修改我的SQL语句....

SELECT 
   rpt.*, 
   ber.shipper, ber.po, ber.commodity, ber.label
   mel.shipper, mel.po, mel.commodity, mel.label

FROM reports rpt

JOIN berries ber ON rpt.inspection_number = ber.report_key
JOIN melons mel ON rpt.inspection_number = mel.report_key

WHERE rpt.status='1'  OR rpt.status='0'
ORDER BY rpt.inspection_number DESC
Run Code Online (Sandbox Code Playgroud)

骗我......

MySQL returned an empty result set (i.e. zero rows). ( Query took 0.0011 sec ) 给了我大中指.我勒个去?有人可以解释我显然做错了什么,以及如何解决它?

Dan*_*ons 5

它并不复杂.你的第一个问题,你是加入反对梅尔但从未做过任何事情,所以你只得到贝尔的数据.你的最后一个查询更接近,而是因为你是内侧连接对浆果和瓜,你不必是任何报告,你会得到任何结果.但答案更接近你在第二个查询中所做的事情,我认为你想要的是:

SELECT 
   rpt.*, 
   COALESCE(ber.shipper, mel.shipper) AS shipper,
   COALESCE(ber.po, mel.po) AS po, 
   COALESCE(ber.commodity, mel.commodity) AS commodity,
   COALESCE(ber.label, mel.label) AS label
FROM reports rpt
LEFT JOIN berries ber ON rpt.inspection_number = ber.report_key
LEFT JOIN melons mel ON rpt.inspection_number = mel.report_key
WHERE rpt.status='1'  OR rpt.status='0'
ORDER BY rpt.inspection_number DESC
Run Code Online (Sandbox Code Playgroud)

这个查询说,给我一些在浆果或甜瓜中加入的行,但对于它们共有的列,给我任何一个存在的.我们先没有特别的原因.

假设这两个表是互斥的,我认为这可以满足您的需求.

编辑:基于@MarcusAdams在下面指出的内容,UNION如果有一些令人讨厌的水果表,可以将其重写为使用a :

SELECT report_key, shipper, po, commodity, label FROM berries
UNION
SELECT report_key, shipper, po, commodity, label FROM melons
UNION
SELECT report_key, shipper, po, commodity, label FROM ...
...
Run Code Online (Sandbox Code Playgroud)

此查询将为您提供一些方便您可以在以后用作子查询(或视图)的方法.您也可以硬编码原始名称,如下所示:

SELECT report_key, shipper, po, commodity, label, 'berries' AS type FROM berries
UNION
SELECT report_key, shipper, po, commodity, label, 'melons' FROM melons
UNION
SELECT report_key, shipper, po, commodity, label, '...' FROM ...
...
Run Code Online (Sandbox Code Playgroud)

然后在原始查询中使用它,你会像这样嵌入它:

SELECT *
FROM reports rpt,
JOIN (SELECT report_key, shipper, po, commodity, label, 'berries' AS type FROM berries
      UNION
      SELECT report_key, shipper, po, commodity, label, 'melons' FROM melons
      UNION
      SELECT report_key, shipper, po, commodity, label, '...' FROM ...
      ...) fruits ON rpt.inspection_number = fruits.report_key
WHERE rpt.status='1'  OR rpt.status='0'
ORDER BY rpt.inspection_number DESC
Run Code Online (Sandbox Code Playgroud)