Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/228.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 在单个查询中填充一对多的结果_Php_Mysql - Fatal编程技术网

Php 在单个查询中填充一对多的结果

Php 在单个查询中填充一对多的结果,php,mysql,Php,Mysql,我有两个表:activity和tag。一个活动有许多标记。我需要优化我们当前的设置,在这里我们找到表中的所有活动,然后迭代每个活动以找到所有标记。最后,我们将内容作为JSON进行处理 以下是一个例子: -- Query that we execute one time SELECT `id`, `name` FROM `activity` -- Query that we execute N times SELECT `id`, `name`, `color` FROM `tag` WHERE

我有两个表:
activity
tag
。一个
活动
有许多
标记
。我需要优化我们当前的设置,在这里我们找到表中的所有活动,然后迭代每个活动以找到所有标记。最后,我们将内容作为JSON进行处理

以下是一个例子:

-- Query that we execute one time
SELECT `id`, `name`
FROM `activity`

-- Query that we execute N times
SELECT `id`, `name`, `color`
FROM `tag`
WHERE `tag`.`activityId` = $activityId
因此,我们的最终代码如下所示:

$result = mysqli_query("
    SELECT `id`, `name`
    FROM `activity`
");

$data = array();

for ($i=0; $i<mysqli_num_rows($result); $i++) {
    $row = mysqli_fetch_assoc($result);

    $data[$i]["activityId"] = $row["id"];
    $data[$i]["name"] = $row["name"];
    $data[$i]["tags"] = array();

    $activityId = $row["id"];

    $resultTags = mysqli_query("
        SELECT `id`, `name`, `color`
        FROM `tag`
        WHERE `tag`.`activityId` = $activityId
    ");

    for ($j=0; $j<mysqli_num_rows($resultTags); $j++) {
        $row = mysqli_fetch_assoc($resultTags);

        $data[$i]["tags"][$j]["name"] = $row["name"];
        $data[$i]["tags"][$j]["color"] = $row["color"];
    }
}
$result=mysqli\u查询(“
选择'id','name`
从`活动`
");
$data=array();

对于($i=0;$iSure just
JOIN
activity表上的标记

您的查询应该如下所示

SELECT activity.id, activity.name, tag.name AS tagName, tag.color AS tagColor
FROM activity
JOIN tag ON tag.activityId = activity.id;
$data = [];
foreach($result as $row) {

    $tags = ["name" => $row["tagName"], "color" => $row["tagColor"]];

    if (isset($data[$row["id"]])) {
        $data[$row["id"]]["tags"][] = $tags; 
    } else {
        $data[$row["id"]] = [
            [
                "id"   => $row["id"],
                "name" => $row["name"],
                "tags" => [$tags],
            ],
        ];
    }

}
$data = [];
foreach($result as $row) {

    $tags = empty($row["tagId"]) ?: ["name" => $row["tagName"], "color" => $row["tagColor"]];

    if (isset($data[$row["id"]]) && $tags) {
        $data[$row["id"]]["tags"][] = $tags; 
    } else {
        $data[$row["id"]] = [
            [
                "id"   => $row["id"],
                "name" => $row["name"],
                "tags" => $tags ? [$tags] : [],
            ],
        ];
    }

}
"1": { "id": 1, "name": "foo", "tags": [ { "tagName": "tag-a", "tagColor": "red" }, { "tagName": "tag-b", "tagColor": "green" }, { "tagName": "tag-c", "tagColor": "blue" } ] }, "2": { "id": 2, "name": "bar", "tags": [ { "tagName": "tag-a", "tagColor": "orange" }, { "tagName": "tag-b", "tagColor": "red" } ] }, "3": { "id": 3, "name": "baz", "tags": [ { "tagName": "tag-a", "tagColor": "purple" } ] }, "4": { "id": 4, "name": "quix", "tags": [] } } 活动表的主键是
id
,并且每一行都是唯一的(即任何给定的
activity.id
的名称都不会更改),则即使没有标记,联接也是安全的。我们将返回至少
N
行,其中
N
tag.activityId
行的数量,这些行在
activity
中具有相应的
id

因此,在PHP中,您可以用这样一个查询构建数组

SELECT activity.id, activity.name, tag.name AS tagName, tag.color AS tagColor
FROM activity
JOIN tag ON tag.activityId = activity.id;
$data = [];
foreach($result as $row) {

    $tags = ["name" => $row["tagName"], "color" => $row["tagColor"]];

    if (isset($data[$row["id"]])) {
        $data[$row["id"]]["tags"][] = $tags; 
    } else {
        $data[$row["id"]] = [
            [
                "id"   => $row["id"],
                "name" => $row["name"],
                "tags" => [$tags],
            ],
        ];
    }

}
$data = [];
foreach($result as $row) {

    $tags = empty($row["tagId"]) ?: ["name" => $row["tagName"], "color" => $row["tagColor"]];

    if (isset($data[$row["id"]]) && $tags) {
        $data[$row["id"]]["tags"][] = $tags; 
    } else {
        $data[$row["id"]] = [
            [
                "id"   => $row["id"],
                "name" => $row["name"],
                "tags" => $tags ? [$tags] : [],
            ],
        ];
    }

}
"1": { "id": 1, "name": "foo", "tags": [ { "tagName": "tag-a", "tagColor": "red" }, { "tagName": "tag-b", "tagColor": "green" }, { "tagName": "tag-c", "tagColor": "blue" } ] }, "2": { "id": 2, "name": "bar", "tags": [ { "tagName": "tag-a", "tagColor": "orange" }, { "tagName": "tag-b", "tagColor": "red" } ] }, "3": { "id": 3, "name": "baz", "tags": [ { "tagName": "tag-a", "tagColor": "purple" } ] }, "4": { "id": 4, "name": "quix", "tags": [] } } 因为活动表中的信息永远不会改变,所以我们只需要附加标记,我们通过在循环中检查
isset($data[$row[“id”]])
来完成

因此,从这里您可以看到两个表的工作示例,其中
活动
中有4行,而
标记
表中有6行。这总共给了我们6行。由于活动表中的一个ID没有任何标记,因此它被从结果集中排除。要返回带有0个标记的行,可以使用
左连接

这意味着空标记行的值为空。所以我们可以修改PHP,使其看起来像这样

SELECT activity.id, activity.name, tag.name AS tagName, tag.color AS tagColor
FROM activity
JOIN tag ON tag.activityId = activity.id;
$data = [];
foreach($result as $row) {

    $tags = ["name" => $row["tagName"], "color" => $row["tagColor"]];

    if (isset($data[$row["id"]])) {
        $data[$row["id"]]["tags"][] = $tags; 
    } else {
        $data[$row["id"]] = [
            [
                "id"   => $row["id"],
                "name" => $row["name"],
                "tags" => [$tags],
            ],
        ];
    }

}
$data = [];
foreach($result as $row) {

    $tags = empty($row["tagId"]) ?: ["name" => $row["tagName"], "color" => $row["tagColor"]];

    if (isset($data[$row["id"]]) && $tags) {
        $data[$row["id"]]["tags"][] = $tags; 
    } else {
        $data[$row["id"]] = [
            [
                "id"   => $row["id"],
                "name" => $row["name"],
                "tags" => $tags ? [$tags] : [],
            ],
        ];
    }

}
"1": { "id": 1, "name": "foo", "tags": [ { "tagName": "tag-a", "tagColor": "red" }, { "tagName": "tag-b", "tagColor": "green" }, { "tagName": "tag-c", "tagColor": "blue" } ] }, "2": { "id": 2, "name": "bar", "tags": [ { "tagName": "tag-a", "tagColor": "orange" }, { "tagName": "tag-b", "tagColor": "red" } ] }, "3": { "id": 3, "name": "baz", "tags": [ { "tagName": "tag-a", "tagColor": "purple" } ] }, "4": { "id": 4, "name": "quix", "tags": [] } } 因此,使用
json_encode
从PHP输出的最终结果,以及SQLFIDLE中的示例数据,应该如下所示

SELECT activity.id, activity.name, tag.name AS tagName, tag.color AS tagColor
FROM activity
JOIN tag ON tag.activityId = activity.id;
$data = [];
foreach($result as $row) {

    $tags = ["name" => $row["tagName"], "color" => $row["tagColor"]];

    if (isset($data[$row["id"]])) {
        $data[$row["id"]]["tags"][] = $tags; 
    } else {
        $data[$row["id"]] = [
            [
                "id"   => $row["id"],
                "name" => $row["name"],
                "tags" => [$tags],
            ],
        ];
    }

}
$data = [];
foreach($result as $row) {

    $tags = empty($row["tagId"]) ?: ["name" => $row["tagName"], "color" => $row["tagColor"]];

    if (isset($data[$row["id"]]) && $tags) {
        $data[$row["id"]]["tags"][] = $tags; 
    } else {
        $data[$row["id"]] = [
            [
                "id"   => $row["id"],
                "name" => $row["name"],
                "tags" => $tags ? [$tags] : [],
            ],
        ];
    }

}
"1": { "id": 1, "name": "foo", "tags": [ { "tagName": "tag-a", "tagColor": "red" }, { "tagName": "tag-b", "tagColor": "green" }, { "tagName": "tag-c", "tagColor": "blue" } ] }, "2": { "id": 2, "name": "bar", "tags": [ { "tagName": "tag-a", "tagColor": "orange" }, { "tagName": "tag-b", "tagColor": "red" } ] }, "3": { "id": 3, "name": "baz", "tags": [ { "tagName": "tag-a", "tagColor": "purple" } ] }, "4": { "id": 4, "name": "quix", "tags": [] } } "1": { “id”:1, “名称”:“foo”, “标签”:[ { “标记名”:“标记a”, “tagColor”:“红色” }, { “标记名”:“标记b”, “标记颜色”:“绿色” }, { “标记名”:“标记c”, “tagColor”:“蓝色” } ] }, "2": { “id”:2, “名称”:“酒吧”, “标签”:[ { “标记名”:“标记a”, “tagColor”:“橙色” }, { “标记名”:“标记b”, “tagColor”:“红色” } ] }, "3": { “id”:3, “名称”:“baz”, “标签”:[ { “标记名”:“标记a”, “tagColor”:“紫色” } ] }, "4": { “id”:4, “名称”:“quix”, “标签”:[] } }
当然,只需加入
活动表上的标记表即可

您的查询应该如下所示

SELECT activity.id, activity.name, tag.name AS tagName, tag.color AS tagColor
FROM activity
JOIN tag ON tag.activityId = activity.id;
$data = [];
foreach($result as $row) {

    $tags = ["name" => $row["tagName"], "color" => $row["tagColor"]];

    if (isset($data[$row["id"]])) {
        $data[$row["id"]]["tags"][] = $tags; 
    } else {
        $data[$row["id"]] = [
            [
                "id"   => $row["id"],
                "name" => $row["name"],
                "tags" => [$tags],
            ],
        ];
    }

}
$data = [];
foreach($result as $row) {

    $tags = empty($row["tagId"]) ?: ["name" => $row["tagName"], "color" => $row["tagColor"]];

    if (isset($data[$row["id"]]) && $tags) {
        $data[$row["id"]]["tags"][] = $tags; 
    } else {
        $data[$row["id"]] = [
            [
                "id"   => $row["id"],
                "name" => $row["name"],
                "tags" => $tags ? [$tags] : [],
            ],
        ];
    }

}
"1": { "id": 1, "name": "foo", "tags": [ { "tagName": "tag-a", "tagColor": "red" }, { "tagName": "tag-b", "tagColor": "green" }, { "tagName": "tag-c", "tagColor": "blue" } ] }, "2": { "id": 2, "name": "bar", "tags": [ { "tagName": "tag-a", "tagColor": "orange" }, { "tagName": "tag-b", "tagColor": "red" } ] }, "3": { "id": 3, "name": "baz", "tags": [ { "tagName": "tag-a", "tagColor": "purple" } ] }, "4": { "id": 4, "name": "quix", "tags": [] } } 活动表的主键是
id
,并且每一行都是唯一的(即任何给定的
activity.id
的名称都不会更改),则即使没有标记,联接也是安全的。我们将返回至少
N
行,其中
N
tag.activityId
行的数量,这些行在
activity
中具有相应的
id

因此,在PHP中,您可以用这样一个查询构建数组

SELECT activity.id, activity.name, tag.name AS tagName, tag.color AS tagColor
FROM activity
JOIN tag ON tag.activityId = activity.id;
$data = [];
foreach($result as $row) {

    $tags = ["name" => $row["tagName"], "color" => $row["tagColor"]];

    if (isset($data[$row["id"]])) {
        $data[$row["id"]]["tags"][] = $tags; 
    } else {
        $data[$row["id"]] = [
            [
                "id"   => $row["id"],
                "name" => $row["name"],
                "tags" => [$tags],
            ],
        ];
    }

}
$data = [];
foreach($result as $row) {

    $tags = empty($row["tagId"]) ?: ["name" => $row["tagName"], "color" => $row["tagColor"]];

    if (isset($data[$row["id"]]) && $tags) {
        $data[$row["id"]]["tags"][] = $tags; 
    } else {
        $data[$row["id"]] = [
            [
                "id"   => $row["id"],
                "name" => $row["name"],
                "tags" => $tags ? [$tags] : [],
            ],
        ];
    }

}
"1": { "id": 1, "name": "foo", "tags": [ { "tagName": "tag-a", "tagColor": "red" }, { "tagName": "tag-b", "tagColor": "green" }, { "tagName": "tag-c", "tagColor": "blue" } ] }, "2": { "id": 2, "name": "bar", "tags": [ { "tagName": "tag-a", "tagColor": "orange" }, { "tagName": "tag-b", "tagColor": "red" } ] }, "3": { "id": 3, "name": "baz", "tags": [ { "tagName": "tag-a", "tagColor": "purple" } ] }, "4": { "id": 4, "name": "quix", "tags": [] } } 因为活动表中的信息永远不会改变,所以我们只需要附加标记,我们通过在循环中检查
isset($data[$row[“id”]])
来完成

因此,从这里您可以看到两个表的工作示例,其中
活动
中有4行,而
标记
表中有6行。这总共给了我们6行。由于活动表中的一个ID没有任何标记,因此它被从结果集中排除。要返回带有0个标记的行,可以使用
左连接

这意味着空标记行的值为空。所以我们可以修改PHP,使其看起来像这样

SELECT activity.id, activity.name, tag.name AS tagName, tag.color AS tagColor
FROM activity
JOIN tag ON tag.activityId = activity.id;
$data = [];
foreach($result as $row) {

    $tags = ["name" => $row["tagName"], "color" => $row["tagColor"]];

    if (isset($data[$row["id"]])) {
        $data[$row["id"]]["tags"][] = $tags; 
    } else {
        $data[$row["id"]] = [
            [
                "id"   => $row["id"],
                "name" => $row["name"],
                "tags" => [$tags],
            ],
        ];
    }

}
$data = [];
foreach($result as $row) {

    $tags = empty($row["tagId"]) ?: ["name" => $row["tagName"], "color" => $row["tagColor"]];

    if (isset($data[$row["id"]]) && $tags) {
        $data[$row["id"]]["tags"][] = $tags; 
    } else {
        $data[$row["id"]] = [
            [
                "id"   => $row["id"],
                "name" => $row["name"],
                "tags" => $tags ? [$tags] : [],
            ],
        ];
    }

}
"1": { "id": 1, "name": "foo", "tags": [ { "tagName": "tag-a", "tagColor": "red" }, { "tagName": "tag-b", "tagColor": "green" }, { "tagName": "tag-c", "tagColor": "blue" } ] }, "2": { "id": 2, "name": "bar", "tags": [ { "tagName": "tag-a", "tagColor": "orange" }, { "tagName": "tag-b", "tagColor": "red" } ] }, "3": { "id": 3, "name": "baz", "tags": [ { "tagName": "tag-a", "tagColor": "purple" } ] }, "4": { "id": 4, "name": "quix", "tags": [] } } 因此,使用
json_encode
从PHP输出的最终结果,以及SQLFIDLE中的示例数据,应该如下所示

SELECT activity.id, activity.name, tag.name AS tagName, tag.color AS tagColor
FROM activity
JOIN tag ON tag.activityId = activity.id;
$data = [];
foreach($result as $row) {

    $tags = ["name" => $row["tagName"], "color" => $row["tagColor"]];

    if (isset($data[$row["id"]])) {
        $data[$row["id"]]["tags"][] = $tags; 
    } else {
        $data[$row["id"]] = [
            [
                "id"   => $row["id"],
                "name" => $row["name"],
                "tags" => [$tags],
            ],
        ];
    }

}
$data = [];
foreach($result as $row) {

    $tags = empty($row["tagId"]) ?: ["name" => $row["tagName"], "color" => $row["tagColor"]];

    if (isset($data[$row["id"]]) && $tags) {
        $data[$row["id"]]["tags"][] = $tags; 
    } else {
        $data[$row["id"]] = [
            [
                "id"   => $row["id"],
                "name" => $row["name"],
                "tags" => $tags ? [$tags] : [],
            ],
        ];
    }

}
"1": { "id": 1, "name": "foo", "tags": [ { "tagName": "tag-a", "tagColor": "red" }, { "tagName": "tag-b", "tagColor": "green" }, { "tagName": "tag-c", "tagColor": "blue" } ] }, "2": { "id": 2, "name": "bar", "tags": [ { "tagName": "tag-a", "tagColor": "orange" }, { "tagName": "tag-b", "tagColor": "red" } ] }, "3": { "id": 3, "name": "baz", "tags": [ { "tagName": "tag-a", "tagColor": "purple" } ] }, "4": { "id": 4, "name": "quix", "tags": [] } } "1": { “id”:1, “名称”:“foo”, “标签”:[ { “标记名”:“标记a”, “tagColor”:“红色” }, { “标记名”:“标记b”, “标记颜色”:“绿色” }, { “标记名”:“标记c”, “tagColor”:“蓝色” } ] }, "2": { “id”:2, “名称”:“酒吧”, “标签”:[ { “标记名”:“标记a”, “tagColor”:“橙色” }, { “标记名”:“标记b”, “tagColor”:“红色” } ] }, "3": { “id”:3, “名称”:“baz”, “标签”:[ { “标记名”:“标记a”, “tagColor”:“紫色” } ] }, "4": { “id”:4, “名称”:“quix”, “标签”:[] } }
谢谢@Sherif,但是我忘了提到我需要通过
activity.id
对表进行
分组,因为我要加入其他几个表。在这种情况下,它不起作用。为什么它不起作用呢?如果
activity.id
是一个PK,那么它应该对这个用例没有影响。包括可疑的
groupby
子句和您声称它不起作用的模式,我很乐意向您展示如何使它起作用。@例如,Serif,我有一个
材料
表,我需要知道我有多少材料用于单个
活动
,所以在我的选择器中,我放置了一个
计数(material.activityId)
,这样就行了