MySQL: левый JOIN против левого JOIN - PullRequest
1 голос
/ 16 августа 2011

У меня есть следующий запрос sql

SELECT * FROM jos_jcalpro_events AS e 
  LEFT JOIN jos_jcalpro_events_seats AS s ON e.extid = s.extid
  LEFT JOIN jos_jcalpro_events_types_xref AS t ON e.extid = t.extid

, который я выполняю через PDO из PHP. Я создаю из этого еще один запрос для повторной вставки в базу данных. Но это не работает. Когда я меняю ЛЕВЫЙ с верхнего на нижний регистр, он делает:

SELECT * FROM jos_jcalpro_events AS e 
  left JOIN jos_jcalpro_events_seats AS s ON e.extid = s.extid
  left JOIN jos_jcalpro_events_types_xref AS t ON e.extid = t.extid

В моей процедуре создания нет никакой разницы, но созданная INSERT имеет фактически на 2 строки меньше. Как это может быть?

Вот важная часть кода:

    $resource = JcalproDataImport::getInstance();

    // IMPORT
    $pdo = $resource->getConnection('import', 'pdo');
    $events = $pdo->query(
        'SELECT * FROM jos_jcalpro_events AS e '
        .'left JOIN jos_jcalpro_events_seats AS s ON e.extid = s.extid '
        .'left JOIN jos_jcalpro_events_types_xref AS t ON e.extid = t.extid;')->fetchAll(PDO::FETCH_ASSOC);

    // MAPPING
    $map = array(
        'picture'=>null, 'cat'=>null, 'day'=>null, 'month'=>null, 'year'=>null, 'recur_type'=>null, 'checked_out'=>null,
      'checked_out_time'=>null, 'payment_type'=>null, 'id'=>null,
      'extid'=>'id', 'contact'=>'contact_info', 'start_date'=>'start', 'end_date'=>'end', 'recur_val'=>'repeat_period',
      'recur_end_type'=>'repeat_end_type_id', 'recur_count'=>'repeat_end_after_occurrences',
      'recur_until'=>'repeat_end_after_date', 'wp_only'=>'only_in_wp', 'eticket'=>'prevent_sending_eticket',
      'region'=>'region_id', 'onlinebooking'=>'online_booking_form', 'organiser'=>'organiser_name'
    );

    // OUTPUT
    $pdo = $resource->switchConnection('export', 'pdo');
    $pdo->query('SET foreign_key_checks = 0');

    foreach ($events as $values)
    {
        $values['chargeable_status'] = (strtolower($values['payment_type']) == 'p') ? 1 : 0;
        $values['repeat_period_type_id'] = $repeat_period_type_map[$values['recur_type']];
        foreach($map as $from=>$to)
        {
            if ($to!== null){ $values[$to] = $values[$from]; }
            unset( $values[$from] );
        }
        $values['created_at'] = '2008-01-01';
        $values['updated_at'] = $values['created_at'];

          if (!$event) {
              foreach ($values as $field=>$value)
              {
                  $sql .= ', '.$field;
                  $sqlValues .= ', "'.mysql_real_escape_string($value).'"';
              }
              $sql = 'INSERT INTO event ( '.substr($sql, 2).' ) VALUES '.PHP_EOL.'( '.substr($sqlValues, 2).' )';
          }else{
              foreach ($values as $value)
              {
                  $sqlValues .= ', "'.mysql_real_escape_string($value).'"';
              }
              $sql .= ', ( '.substr($sqlValues, 2).' )';
          }
        $event[] = $values;
    }
    $pdo->query($sql)

Но он отлично работает для других запросов, так что я не могу поверить в проблему там.

1 Ответ

2 голосов
/ 16 августа 2011
  1. Нет причины, по которой left JOIN работал бы иначе, чем LEFT JOIN. Это вряд ли связано с вашей проблемой.

  2. Сопоставьте имя вашего столбца с псевдонимами столбца в вашем SELECT.

  3. Пропустите столбцы, которые вам не нужны, присвоив им имена, которые вам нужны, вместо использования SELECT *.

  4. Подготовьте INSERT один раз с именованными параметрами, совпадающими с именами псевдонимов столбцов. Затем используйте execute($values), чтобы вставить каждую строку, извлеченную из SELECT.

Вот примерно так я бы написал:

$map = array(
  'extid'=>'id', 
  'contact'=>'contact_info', 
  'start_date'=>'start', 
  'end_date'=>'end',
  'recur_val'=>'repeat_period', 
  'recur_end_type'=>'repeat_end_type_id', 
  'recur_count'=>'repeat_end_after_occurrences',
  'recur_until'=>'repeat_end_after_date',
  'wp_only'=>'only_in_wp',
  'eticket'=>'prevent_sending_eticket',
  'region'=>'region_id',
  'onlinebooking'=>'online_booking_form',
  'organiser'=>'organiser_name',
  'CURDATE()'=>'created_at',
  'CURDATE()'=>'updated_at',
);

$aliasize = function($alias, $column) { return "$column AS $alias"; }
$select_list = join(",", array_walk($aliasize, $map));

$events = $pdo->query("SELECT $select_list FROM ...")
    ->fetchAll(PDO::FETCH_ASSOC);

$column_list = join(",", array_values($map));
$parameterize = function($alias) { return ":$alias"; }
$param_list = join(",", array_map($parameterize, $map));

$insert = $pdo->prepare("INSERT INTO event ($column_list) VALUES ($param_list)");

foreach ($events as $values) {
    $insert->execute($values);
}
...