簡體   English   中英

MySQL聯接不能與可選字段一起使用

[英]MySQL join not working with optional fields

我在使用內部聯接和左聯接的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字段的值,而兩個外鍵均返回空白,即使其中一個不是空白也是如此。 我嘗試了所有組合排列(左,內,右)的不同組合,但沒有一個能提供理想的結果。

我很沮喪! 預先感謝您的任何幫助!

昨天我花了大部分時間試圖用簡化版的應用程序重現該問題,最終我做到了。 事實證明,在第二個外鍵(在我的簡化示例中為event_id)開頭的一系列連接中,在下一個表格中重復了第一個外鍵(在簡化示例中為art_id)。 因此,我的猜測是,如果'event_id'為null,則'artist_id'將被null值覆蓋,因為查詢將為'event_id'之后的所有內容返回空值。 因此,問題不在於LEFT JOIN的工作原理,而在於子表中第一個外鍵的重復,該重復依賴於允許為空的第二個外鍵。 我顯然需要重新訪問我的表結構...

非常感謝所有建議!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM