У меня есть запрос MySQL, который используется LEFT JOIN
несколько раз для подключения разных таблиц, где они author
одинаковы. Однако, когда я echo
показываю результат, он возвращает мне тонны повторяющихся строк (на самом деле 32,920
), когда у меня только 4 строки записаны в grouppost
таблице и около 100 - в остальных трех.
Таблица status
+----+------+--------------+--------+------+-------+---------------------+
| id | osid | account_name | author | type | data | postdate |
+----+------+--------------+--------+------+-------+---------------------+
| 1 | 1 | John | John | a | lkjg. | 2018-01-01 00:00:00 |
+----+------+--------------+--------+------+-------+---------------------+
Таблица article_status
+----+------+--------------+--------+------+-------+------+---------------------+
| id | osid | account_name | author | type | data | artid | postdate |
+----+------+--------------+--------+------+-------+------+---------------------+
| 2 | 1 | John | John | a | bcda. | 1 | 2018-01-01 00:00:00 |
+----+------+--------------+--------+------+-------+------+---------------------+
Таблица grouppost
+----+-----+--------+--------+------+-------+----------------------+
| id | pid | gname | author | type | data | pdate |
+----+-----+--------+--------+------+-------+----------------------+
| 3 | 1 | Group1 | John | 1 | ABCD. | 2018-01-01 00:00:00 |
+----+-----+--------+--------+------+-------+----------------------+
Таблица photos_status
+----+------+--------------+--------+------+-------+------+---------------------+
| id | osid | account_name | author | type | data | photo | postdate |
+----+------+--------------+--------+------+-------+------+---------------------+
| 4 | 1 | John | John | a | abcd. | a.jpg | 2018-01-01 00:00:00 |
+----+------+--------------+--------+------+-------+------+---------------------+
Ожидаемый результат - объединить четыре строки вместе и получить id
из них с указанными именами:
+---------+--------+-------+-------+
| stat_id | art_id | gr_id | ph_id |
+---------+--------+-------+-------+
| 1 | 2 | 3 | 4 |
+---------+--------+-------+-------+
Запрос MySQL:
$sql = "
SELECT a.id AS art_id
, g.id AS gr_id
, p.id AS ph_id
, s.id AS stat_id
FROM article_status AS a
LEFT
JOIN grouppost AS g
ON a.author = g.author
LEFT
JOIN photos_status AS p
ON a.author = p.author
LEFT
JOIN status AS s
ON a.author = s.author
AND a.author = 'John'
AND g.author = 'John'
AND p.author = 'John'
AND s.author = 'John'
";
$stmt = $conn->prepare($sql);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
echo $row["gr_id"]."<br>"; // returns back duplicate rows
}
$stmt->close();
mysqli_close($conn);
Поиск возможных ошибок:
var_dump ($ результат): object(mysqli_result)#3 (5) { ["current_field"]=> int(0) ["field_count"]=> int(4) ["lengths"]=> NULL ["num_rows"]=> int(32920) ["type"]=> int(0) }
Как и в var_dump
предыдущем случае, ["field_count"]=> int(4)
это правильно, поскольку в запросе задействовано 4 поля. Однако ["num_rows"]=> int(32920)
возвращается 32 920, что совершенно неверно.
var_dump ($ stmt): object(mysqli_stmt)#2 (10) { ["affected_rows"]=> int(0) ["insert_id"]=> int(0) ["num_rows"]=> int(0) ["param_count"]=> int(0) ["field_count"]=> int(4) ["errno"]=> int(0) ["error"]=> string(0) "" ["error_list"]=> array(0) { } ["sqlstate"]=> string(5) "00000" ["id"]=> int(1) }
Опять же , я хотел бы, чтобы выбрать все затронутые строки из article_status
, grouppost
, photos_status
и status
таблиц , где author
такого же, как John
в примере.
Во-первых, ваш запрос следует упростить до следующего:
SELECT
a.id art_id,
g.id gr_id,
p.id ph_id,
s.id stat_id
FROM
article_status a
LEFT JOIN grouppost g
ON a.author = g.author
LEFT JOIN photos_status p
ON a.author = p.author
LEFT JOIN status s
ON a.author = s.author
where
a.author = 'John'
вы явно повторно добавляли AND author = 'John' для каждого из ваших других присоединений. Они должны были остаться с соответствующим предложением «ON», а не сгруппированы в конце. Кроме того, через транзитивную ассоциацию ex:
A = B and B = C, therefore A = C.
Если вы уже присоединяетесь к AUTHOR между каждой соответствующей таблицей, наличие единственного предложения WHERE для «a.author = 'John'» также отразит все остальные как «John».
Что касается дубликатов, может ли это быть основано на декартовом результате, что у вас есть несколько записей «Джон» как у автора, и он присоединяется к каждому другому идентификатору на основе имени, а не того, что, по вашему мнению, вы хотели получить.
Ex Данные.
Article Status
id author author_lastName
1 John A
2 Bill E
3 John H
4 Mary J
5 John M
GroupPost
id author author_lastname
1 Mary J
2 John M
3 John M
4 John A
5 Bill E
6 John H
Итак, только из приведенного выше примера из двух таблиц, для каждого «John» в таблице Article он находит все имена «John» в таблице GroupPost и в результате
Article ID GroupPostIT
1 (John A) 2 (John M)
1 (John A) 3 (John M)
1 (John A) 4 (John A)
1 (John A) 6 (John H)
3 (John H) 2 (John M)
3 (John H) 3 (John M)
3 (John H) 4 (John A)
3 (John H) 6 (John H)
6 (John M) 2 (John M)
6 (John M) 3 (John M)
6 (John M) 4 (John A)
6 (John M) 6 (John H)
Теперь перенесите это и на другие столы, и вы увидите, что получите больше, чем ожидаете. Вероятно, вам понадобится лучшая ассоциация «ID» между таблицами, чем общее имя, которое было бы обычным.
Например, ваш GroupPost должен иметь authorID, а не просто имя ... то же самое с другими таблицами.
Эта статья взята из Интернета, укажите источник при перепечатке.
Если есть какие-либо нарушения, пожалуйста, свяжитесь с[email protected] Удалить.
я говорю два предложения