MySQL加入不使用可选字段

时间:2015-07-09 13:06:48

标签: php mysql

我在使用内部和左侧连接的MySQL查询时遇到问题。问题是,如果允许NULL的字段中主表中的外键为空,则查询不会读取主表中的所有字段。

我的任务是用MySQL组织录音列表,其中一些是现场录音,而另一些是录音室录音。出于这个问题的目的,我正在简化表结构如下:

table name: recordings
fields:
recording_id INT AUTO-INCREMENT
recording_name VARCHAR NOT NULL
artist_id INT NOT NULL FOREIGN KEY
event_id INT NULL FOREIGN KEY

table name: artists
fields:
artist_id INT AUTO-INCREMENT
artist_name VARCHAR NOT NULL

table name: events
fields:
event_id INT AUTO-INCREMENT
event VARCHAR NOT NULL
venue_id INT NOT NULL FOREIGN KEY

table_name: venues
fields:
venue_id INT AUTO-INCREMENT
venue_name VARCHAR NOT NULL
address VARCHAR NOT NULL

如果现场录制,我想要提供录制完成事件的详细信息,如果是录音室录音,我将事件字段留空。换句话说,在recordings表中event_id是一个可选字段,但始终需要artist_id

要编辑recordings表中的现有记录,我有一个包含三个字段的表单(再次简化):

<form>
  <input name="recording_name" type="text" value="<?php $recording_name ?>" />
  <select name="artist_id">
     <option>Select option</option>
     <option <?php $selected ?> value="1">Artist 1</option>
     etc.
  </select>
  <select name="event_id">
     <option>Select option</option>
     <option <?php $selected ?> value="1">Venue 1</option>
     etc.
  </select>  
</form>

我使用$selected变量显示与表单下拉列表中从数据库中提取的现有值相对应的选项,如下所示:

$selected = ($existing_value == $option_id ? 'selected="selected" : '');

现在,为了获取表单的现有值,我有以下SQL查询:

$recording_sql = 
'SELECT * FROM recordings 
INNER JOIN artists ON recordings.artist_id = artists.artist_id 
LEFT JOIN events ON recordings.event_id = events.event_id
LEFT JOIN venues ON events.venue_id = venues.venue_id'

然后,填充两个下拉列表:

$artist_sql = 
'SELECT * FROM artists'

$event_sql = 
SELECT * FROM events 
INNER JOIN venues ON events.venue_id = venues.venue_id

我的PHP代码看起来像这样:

function buildForm($result){
  $data = $result->fetch_array($MYSQLI_ASSOC))
  $form = '<input name="recording_id" type="hidden" value="'.$data['recording_id'].'" />';
  $form .='<input name="recording_name" type="text" value="'.$data['recording_name'].'" />';
  $form .= buildSelectBox('artists', $data['artist_id']);
  $form .= buildSelectBox('events', $data['event_id']);
  return $form;
}

function buildSelectBox($table, $existing_id = NULL){
  //run SQL to pull data from relevant table (i.e. $artist_sql, or $event_sql which includes join to 'venues')
  //Loop through $mysqli_result to build each option
  while(etc....){
    $selected = ($existing_id == $option_id ? 'selected="selected" : '');
    $options_list .= '<option'.$selected.'value="'.$id.'">'.$artist_name.'</option>';
  }
  return $options_list;
}

如果两个外键都有值,这可以正常工作。但是,当event_id中的recordings字段为空时,它也不会读取其他外键。它读取文本字段recording_name,虽然很好。换句话说,我为$recordings_sql获得的结果集仅包含recording_name字段的值,而两个外键都返回空白,即使其中一个不为空。我已经尝试了不同组合中的所有连接排列(左,内,右),但它们都没有给出所需的结果。

我很难过!提前感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

我昨天大部分时间都在尝试使用我的应用程序的简化版本重现问题,最终我做到了。事实证明,第一个外键(在我的简化示例中为artist_id)在另一个表中重复,该表以一系列以第二个外键开头的连接(在我的简化示例中为event_id)开始。所以,我的猜测是,如果'event_id'为null,'artist_id'会被空值覆盖,因为如果'event_id'为空,查询将为'event_id'之后的所有内容返回空值。因此,问题不在于LEFT JOIN如何工作,而是在子表中重复第一个外键,该子表依赖于允许为空的第二个外键。我显然需要重新审视我的表结构...

非常感谢所有的建议!