Мы добавили два столбца к нашей основной таблице MySQL (именованные объекты), столбец для количества и столбец для идентификатора единиц. Если количество и / или единицы измерения неизвестны, для этих столбцов устанавливается значение NULL.
Мы хотели объединить эту таблицу с таблицей типов единиц измерения, чтобы отобразить названия единиц (фунты, страницы, граммы и т. Д.).
Когда я запускаю SELECT в клиенте командной строки MYSQL, он возвращает ожидаемые результаты. Когда моя страница PHP запускает запрос, в первой строке отображаются значения с неправильной стороны объединения.
Пример: объединяемые таблицы являются объектами и типами объектов с этими определениями
mysql> show create table objects;
CREATE TABLE `objects` (
`objId` int NOT NULL AUTO_INCREMENT,
`name` varchar(100) DEFAULT NULL,
`description` varchar(250) DEFAULT NULL,
`quantity` int DEFAULT NULL,
`unitid` int DEFAULT NULL,
`create_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`modify_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`objId`),
KEY `unitid` (`unitid`),
CONSTRAINT `objects_ibfk_1` FOREIGN KEY (`unitid`) REFERENCES `unittypes` (`unitId`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=4735 DEFAULT CHARSET=utf8
и:
mysql> show create table unittypes;
CREATE TABLE `unittypes` (
`unitId` int NOT NULL AUTO_INCREMENT,
`name` varchar(50) DEFAULT NULL,
`description` varchar(50) DEFAULT NULL,
`create_date` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
`modify_date` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`unitId`),
UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8
Примеры строк:
Unittypes:
+--------+------+--------------+-
| unitId | name | description |
+--------+------+--------------+-
| 1 | Each | Each |
Objects:
+-------+---------------------------------------+-------------+----------+--------+
| objId | NAME | description | quantity | unitid |
+-------+---------------------------------------+-------------+----------+--------+
| 1018 | UNKNOWN cables | NULL | NULL | NULL |
| 3466 | UNKNOWN replies | NULL | NULL | NULL |
+-------+---------------------------------------+-------------+----------+--------+
| 722 | Soundgarden-Loudest Love | NULL | 1 | 1 |
| 4703 | Soundgarden-Live FROM The Artists Den | NULL | 1 | 1 |
+-------+---------------------------------------+-------------+----------+--------+
Пример запроса на соединение:
SELECT o.objid, o.name, o.description,
o.quantity, u.name, u.description, o.create_date, o.modify_date
FROM objects AS o
LEFT JOIN unittypes u USING(unitid)
WHERE o.NAME LIKE '%Soundgarden-L%'
В MYSql клиенте командной строки возвращает:
+-------+---------------------------------------+-------------+----------+------+-------------+---------------------+---------------------+
| objid | name | description | quantity | name | description | create_date | modify_date |
+-------+---------------------------------------+-------------+----------+------+-------------+---------------------+---------------------+
| 722 | Soundgarden-Loudest Love | NULL | 1 | Each | Each | 2017-04-01 05:44:56 | 2020-01-15 08:59:45 |
| 4703 | Soundgarden-Live From The Artists Den | NULL | 1 | Each | Each | 2019-09-17 21:52:26 | 2020-01-15 08:59:45 |
+-------+---------------------------------------+-------------+----------+------+-------------+---------------------+---------------------+
На странице PHP он возвращает (PHP страница вернула ожидаемые результаты без объединения:
objid name description quantity create_date modify_date
722 Each Each 1 2017-04-01 05:44:56 2020-01-15 08:59:45
4703 Soundgarden-Live From The Artists Den NULL 1 Each Each 2019-09-17 21:52:26 2020-01-15 08:59:45
Набор результатов имеет 3 строки.
Пример, когда юнит-типы не имеют подходящей строки:
В клиенте командной строки:
SELECT o.objid, o.name, o.description,
o.quantity, u.name, u.description, o.create_date, o.modify_date
FROM objects AS o
LEFT JOIN unittypes u USING(unitid)
WHERE o.NAME LIKE '%unknown %';
Результат:
+-------+--------------------------------------------------+-------------+----------+------+-------------+---------------------+---------------------+
| objid | name | description | quantity | name | description | create_date | modify_date |
+-------+--------------------------------------------------+-------------+----------+------+-------------+---------------------+---------------------+
| 1018 | Unknown cables | NULL | NULL | NULL | NULL | 2017-06-27 02:22:12 | 2017-06-27 02:22:12 |
| 3466 | Unknown replies | NULL | NULL | NULL | NULL | 2018-11-05 01:45:17 | 2018-11-05 01:45:17 |
|
В PHP страница:
objid name description quantity create_date modify_date
1018 NULL NULL NULL 2017-06-27 02:22:12 2017-06-27 02:22:12
3466 Unknown replies NULL NULL NULL NULL 2018-11-05 01:45:17 2018-11-05 01:45:17
Я получаю те же результаты, используя синтаксис соединения
оставленные типы юнитов соединения u для o.unitid = u.unitid
PHP код, который выполняет запрос:
if ($result = $GLOBALS['DB']->query($selObj)) {
if ($row = $result->fetch_assoc()) {
$row_cnt = $result->num_rows;
echo '<table><tr>';
foreach(array_keys($row) as $heading) echo "<th>$heading</th>";
echo '</tr>';
/* process result set */
do {
echo '<tr>';
foreach($row as $item) echo '<td>'.($item==NULL?'NULL':$item).'</td>';
echo '</tr>';
} while ($row = $result->fetch_row()); // get next result set
echo '</table>';
printf("Result set has %d row%s.<br><br>", $row_cnt,($row_cnt==1?"":"s"));
$result->close();
} else echo 'Empty result set<br><br>';
} else echo $DB->error;
Я ожидаю, что один и тот же запрос будет вести себя одинаково в обоих примерах. Я бы предположил, что командная строка и PHP просто передают строку mySQL для обработки, но, очевидно, есть некоторая разница, которую я не вижу.
Есть ли что-то странное в том, как PHP передает запрос; MYsql не обрабатывает соединения через этот интерфейс должным образом; код неправильный (работает без объединения)?
(я также спрашивал об этом по https://dba.stackexchange.com/q/258940/200179)