【问题标题】:MySQL LEFT JOIN tables or PHP combine arraysMySQL LEFT JOIN 表或 PHP 组合数组
【发布时间】:2016-10-06 12:30:16
【问题描述】:

我被困住了,我希望得到您的帮助(建议)。我正在使用 PHP 和 Mysql,我的问题如下所示。

这是我想要实现的简化版本。我有两张表,一张是city list,一张是departments。我想 LEFT JOIN 这两个表(如果可能)并返回所有城市的列表,即使表 bus_departures 中没有连接的记录。

我可以只使用 MySQL 来完成吗,或者我必须在 PHP 中组合数组。我想看看你的解决方案。谢谢。

城市

-------------------     
ID | CITY               
-------------------     
1   | London            
2   | Paris             
3   | New York          
4   | Rome              
5   | Zagreb            

Bus_Departures

------------------------------------------
ID  | DATE          | CITY          | No. DEPARTURES
------------------------------------------
1   | 2016-06-06    | 1             | 5
2   | 2016-06-06    | 4             | 3
3   | 2016-06-06    | 3             | 2
4   | 2016-06-07    | 3             | 4
5   | 2016-06-07    | 1             | 1
6   | 2016-06-08    | 3             | 8
7   | 2016-06-09    | 1             | 3
8   | 2016-06-09    | 4             | 2

选择

SELECT * FROM City LEFT JOIN Bus_Departures WHERE date = '2016-06-07' ORDER BY City ASC

返回

London      2016-06-07      1
New York    2016-06-07      4

我想向用户回应这个

London      2016-06-07      1
New York    2016-06-07      4
Paris       2016-06-07      - (no records at all)
Rome        2016-06-07      - (no records for this day)
Zagreb      2016-06-07      - (no records at all)

谢谢!

【问题讨论】:

  • 您让任何人都很难复制粘贴您的数据/表格。请将它们作为两个单独的部分发布,而不是并排发布。也张贴数字而不是 1(伦敦)等。我们可以弄清楚谢谢
  • 左连接没问题,但是在执行left join 之后,您的 WHERE 语句位于右侧表上。因此,例如,您加入的巴黎条目看起来像 Paris NULL NULL 并且未被选中,就像两个罗马条目看起来像 Rome 2016-06-06 3Rome 2016-06-09 2
  • 感谢e4c5的批评,下次我会尝试发布更多用户友好的表格!再次感谢 Elijan9。

标签: php mysql sql arrays join


【解决方案1】:

您当然需要为您的用例做一个LEFT JOIN,但在您当前的语句中,您的WHERE 语句将在已经连接的表上运行。因此,在使用 WHERE 子句之前,已连接的表将如下所示:

London            | 2016-06-06  | 5
Rome              | 2016-06-06  | 3
New York          | 2016-06-06  | 2
New York          | 2016-06-07  | 4
London            | 2016-06-07  | 1
New York          | 2016-06-08  | 8
London            | 2016-06-09  | 3
Rome              | 2016-06-09  | 2
Paris             | NULL        | NULL
Zagreb            | NULL        | NULL

现在很明显WHERE date = '2016-06-07' 不会返回您想要的数据。

但是,如果您在 join 子句中包含您的日期要求,它将起作用,例如:

SELECT * FROM City LEFT JOIN Bus_Departures
  ON (City.ID = Bus_Departure.CITY AND Bus_Departure.date = '2016-06-07')
  ORDER BY City ASC

在这种情况下,LEFT JOIN 仅在右侧执行:

------------------------------------------
ID  | DATE          | CITY          | DEPARTURES
------------------------------------------
4   | 2016-06-07    | 3             | 4
5   | 2016-06-07    | 1             | 1

(它也会运行得更快。)

由于您还希望结果中包含日期,因此完整的语句可能如下所示:

SELECT City.CITY, '2016-06-07', Bus_Departure.DEPARTURES 
  FROM City LEFT JOIN Bus_Departures
  ON (City.ID = Bus_Departure.CITY AND Bus_Departure.date = '2016-06-07')
  ORDER BY City.ID ASC

【讨论】:

  • 你帮了我很大的忙 Elijan9,谢谢!这正是我所需要的,你甚至一步一步地解释了它!谢谢
【解决方案2】:

当您执行 where 子句时,您会限制删除所有空值的日期。如果您仍想在结果中看到它们,则需要在查询中包含空检查。

select c.CITY, bd.DATE, bd.DEPARTURES from city c
left join bus_departures as bd on bd.city = c.id
where bd.DATE='2016-06-07' or bd.DATE is null;

【讨论】:

  • 如果一个城市在 Departures 中有条目,那将不起作用,只是不在请求的日期(例如主题启动器示例中的罗马)
猜你喜欢
  • 2012-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-12
  • 1970-01-01
  • 2016-05-27
相关资源
最近更新 更多