我有一个MySQL查询,该查询多次使用LEFT JOIN
来连接author
相同的不同表。但是,当我echo
得出结果时,如果我在32,920
表中只记录了4行,而在其他三行中记录了约100行,则会给我返回大量重复行(实际上是grouppost
) 。
表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($ result): 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
。
答案 0 :(得分:2)
首先,您的查询应简化为以下内容。
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”子句,而不是最后分组。另外,通过传递关联,例如:
A = B and B = C, therefore A = C.
如果您已经在每个表之间加入了AUTHOR,那么为“ a.author ='John'”拥有一个WHERE子句也将所有其余的都捕获为'John'。
对于重复项,可能是基于笛卡尔结果,即您作为作者有多个“约翰”记录,并且正在根据名称而不是您想获得的名称与其他所有ID联接。 / p>
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
因此,仅从上述两个表的示例中,对于Article表中的每个“ John”,它都会在GroupPost表中找到所有“ John”名称,并得出
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,而不仅仅是名称...与其他表相同。