简短的回答是否定的,它不能完成。但是,它与 PDO 无关。它与 MySQL 有关:MySQL 不是 PHP。它的工作是存储和获取数据。如果您JOIN 2 个或更多表并获取结果,那么数据库将很乐意这样做。
然后将“按原样”获取数据,也就是说:以几乎与存储数据相同的方式。如果您想要一个二维数组,这意味着数据存储在一个表中,该表包含本身就是表的字段。 MySQL 不这样做:它没有嵌套表(例如,MS SQL Server 可以通过将 XML 存储在字段中来做到这一点)。
然而,PHP 可以处理查询返回的数据,使用一个简单的循环:
$stmt = $pdo->query(
'SELECT u.*, p.id as picture_id, p.name as picture_name
FROM users u
LEFT JOIN pictures p
ON u.id = p.user_id
');
$endResult = array();
while($row = $stmt->fetch(PDO::FETCH_ASSOC))
{
if (!isset($endResult[$row['id']]))
$endResult[$row['id']] = array(
'id' => $row['id'],
'username' => $row['username'],
'pictures' => array();
);
$endResult[$row['id']]['pictures'][] = array(
'id' => $row['picture_id'],
'name' => $row['picture_name']
);
}
真的是那么简单。您可能也知道:亲吻是最重要的。接下来的内容纯属学术性的。下面列出的代码不应使用,但我有点得意忘形,不“保留”查询似乎很可惜我的疯狂时刻产生了......所以我把它贴在这里
此代码不可使用。永远!
这样做可能会对您自己、您周围的人和整个人类造成严重和永久性的伤害。如果您是那种在阅读此答案的其余部分时可能会想“嘿,我可能会使用这个”的人,请不要再读了。并获得帮助。
当然,还有其他选择。例如,您可以通过按用户 ID 对结果集进行分组来减少获取的行数。如果你这样做,你必须GROUP_CONCATpictures 表中的值。我不建议这样做,因为它取代了逻辑:逻辑属于应用程序,而不是数据库服务器或查询,只要知道这是可能的:
SELECT u.*,
GROUP_CONCAT(p.id) AS picture_ids,
GROUP_CONCAT(p.name) AS picture_names
FROM users u
LEFT JOIN pictures p?
ON u.id = p.user_id
GROUP BY u.id;
默认情况下,MySQL 将使用逗号作为分隔符连接pictures 表中的值。在这种情况下,只需 explode-ing 将结果放入数组中即可:
$results = array();
while ($row = $stmt->fetch(PDO::FETCH_ASSOC))
{
$pictures = array();
$ids = explode(',', $row['picture_ids']);
$names = explode(',', $row['picture_names']);
foreach ($ids as $k => $id)
{
$pictures[] = array(
'id' => $id,
'name' => $names[$k]
);
}
$results[] = array(
'id' => $row['id'],
'username' => $row['username'],
'pictures' => $pictures
);
}
当然,如果图片名称包含逗号,上面的代码将完全失败,因此最好更改GROUP_CONCAT使用的分隔符:
GROUP_CONCAT(p.name, '@#@#@')
或者,REPLACE 带有分号的逗号:
GROUP_CONCAT(REPLACE(p.name, ',', ';'))
但由于我们要深入挖掘:一分钱,一英镑,您不妨编写一个查询,选择pictures 数据作为json 编码字符串。我们需要为此做些什么?简单:
-
CONCAT 将数据转换成类似[{"id":%d, "name":"%s"]} 的字符串格式,其中 %d 是一个 int,%s 是图片的名称。
- 我们还必须确保图片名称中不包含
",因为这会导致 JSON 格式错误。添加转义 \ 很危险,因为这样的反斜杠可能已经存在。
- 获取数据,然后
json_decodepictures 数据。
对于如此简单的任务,生成的查询非常复杂,但它是:
SELECT u.*,
CONCAT(
'[',
GROUP_CONCAT(
CONCAT(
'{"id":',
p.id,
',"name":"',
REPLACE(
p.name,
'"',
'"'
),
'"}'
)
),
']'
) AS pictures
FROM users u
LEFT JOIN pictures p
ON u.id = p.user_id
GROUP_BY u.id;
在你的 PHP 脚本中,写:
$stmt = $pdo->query();//<-- the query from above
$result = array();
while($row = $stmt->fetch(PDO::FETCH_ASSOC))
{
$row['pictures'] = json_decode($row['pictures'], true);
$result[] = $row;
}
但老实说,这不值得麻烦。只需按原样执行您的查询,然后编写我在答案开头使用的那个简单循环。因为这最后一个 sn-p Though fully functional,简直是白痴。如果这确实是您希望数据库返回的那种数据,请切换到像 mongoDB 这样的NoSQL alternative,而不是重新处理此查询以最终得到只有疯子才会看到并认为它是一种可能性的东西:
SELECT
CONCAT(
'{"id":',
u.id,
',"username":"',
REPLACE(
u.username,'"','"'
),'","pictures":',
CONCAT(
'[',
GROUP_CONCAT(
CONCAT(
'{"id":',
p.id,
',"name":"',
REPLACE(
p.name,
'"',
'"'
),
'"}'
)
),
']'
),
'}'
) AS full_json
FROM users u
LEFT JOIN pictures p
ON u.id = p.user_id
GROUP_BY u.id;
//in PHP:
$result = array();
while($row = $stmt->fetch(PDO::FETCH_ASSOC))
$result = json_decode($row['full_json'], true);
但如果您想知道:it does work。