如何使用 INNER JOIN 改进我的 php sub_array 代码以在 DataTables 上显示数据?

Posted

技术标签:

【中文标题】如何使用 INNER JOIN 改进我的 php sub_array 代码以在 DataTables 上显示数据?【英文标题】:How to improve my php sub_array code using INNER JOIN to display data on DataTables? 【发布时间】:2019-07-04 10:58:18 【问题描述】:

我正在使用这个 CRUD 教程 https://www.webslesson.info/2017/01/php-pdo-ajax-crud-with-data-tables-and-bootstrap-modals.html 进行一些测试,我想改进它,包括与 mysql 上的另一个表相关的 2 列。

我正在使用下面的教程文件:

    一个获取数据以显示在 DataTables (fetch.php) 上的 php 文件; 一个 index.php 文件; 一个调用“用户”的表,它有 4 列:
Users table
-------------------------------------
id | first_name | last_name | image

我创建了 2 个与“用户”表相关的表。他们是:

    “type_service”表,包含列(“typeID”和“type”)和 “类别”表,包含列(“categoryID”和“category”)。

在“users”表中,我包含了 2 列,分别称为“type_fk”和“category_fk”,其中“fk”是外键:

Users table
----------------------------------
id | first_name | last_name | image | type_fk | category_fk 

在创建列时,它们与关系完美的“用户”表相关。

在此之后,我在 fetch.php 文件中包含了一个 INNER JOIN 查询,如下所示:

$query .= "SELECT users.*, type_service.type, categories.category FROM 用户 INNER JOIN type_service ON users.type_fk = type_service.typeID INNER JOIN 类别 ON users.category_fk = categories.categoryID ";

Fetch.php 文件:

<?php
include('db.php');
include('function.php');
$query = '';
$output = array();

    $query .= "SELECT users.*, type_service.type, categories.category 
    FROM users 
    INNER JOIN type_service ON users.type_fk = type_service.typeID
    INNER JOIN categories ON users.category_fk = catgories.categoryID

 ";

if(isset($_POST["search"]["value"]))

 $query .= 'WHERE first_name LIKE "%'.$_POST["search"]["value"].'%" ';
 $query .= 'OR last_name LIKE "%'.$_POST["search"]["value"].'%" ';

if(isset($_POST["order"]))

 $query .= 'ORDER BY '.$_POST['order']['0']['column'].' '.$_POST['order']['0']['dir'].' ';

else

 $query .= 'ORDER BY id DESC ';

if($_POST["length"] != -1)

 $query .= 'LIMIT ' . $_POST['start'] . ', ' . $_POST['length'];

$statement = $connection->prepare($query);
$statement->execute();
$result = $statement->fetchAll();
$data = array();
$filtered_rows = $statement->rowCount();
foreach($result as $row)

 $image = '';
 if($row["image"] != '')
 
  $image = '<img src="upload/'.$row["image"].'" class="img-thumbnail"   />';
 
 else
 
  $image = '';
 
 $sub_array = array();
 $sub_array[] = $image;
 $sub_array[] = $row["first_name"];
 $sub_array[] = $row["last_name"];
 $sub_array[] = $row["type"];
 $sub_array[] = $row["category"];
 $sub_array[] = '<button type="button" name="update" id="'.$row["id"].'" class="btn btn-warning btn-xs update">Update</button>';
 $sub_array[] = '<button type="button" name="delete" id="'.$row["id"].'" class="btn btn-danger btn-xs delete">Delete</button>';
 $data[] = $sub_array;

$output = array(
 "draw"    => intval($_POST["draw"]),
 "recordsTotal"  =>  $filtered_rows,
 "recordsFiltered" => get_total_all_records(),
 "data"    => $data
);
echo json_encode($output);
?>

在上面的代码中包含 INNER JOIN 查询后,我在同一个文件 (fetch.php) 中包含了 2 个子数组,如下所示:

$sub_array[] = $row["type"]; $sub_array[] = $row["category"];

代码如下:

 $sub_array = array();
 $sub_array[] = $image;
 $sub_array[] = $row["type"];
 $sub_array[] = $row["category"];
 $sub_array[] = $row["first_name"];
 $sub_array[] = $row["last_name"];
 $sub_array[] = '<button type="button" name="update" id="'.$row["id"].'" class="btn btn-warning btn-xs update">Update</button>';
 $sub_array[] = '<button type="button" name="delete" id="'.$row["id"].'" class="btn btn-danger btn-xs delete">Delete</button>';
 $data[] = $sub_array;

上面的代码执行后,index.php页面通过下面的html代码显示数据:

<body>
        <div class="container box">
            <h1 align="center">PHP PDO Ajax CRUD with Data Tables and Bootstrap Modals</h1>
            <br />
            <div class="table-responsive">
                <br />
                <div align="right">
                    <button type="button" id="add_button" data-toggle="modal" data-target="#userModal" class="btn btn-info btn-lg">Add</button>
                </div>
                <br /><br />
                <table id="user_data" class="table table-bordered table-striped">
                    <thead>
                        <tr>
                            <th >Image</th>
                            <th >Type</th>
                            <th >Category</th>
                            <th >First Name</th>
                            <th >Last Name</th>
                            <th >Edit</th>
                            <th >Delete</th>
                        </tr>
                    </thead>
                </table>

            </div>
        </div>
    </body>

当我刷新 index.php 页面时,DataTable 返回一个无效的 JSON 响应,如下图所示:

https://imgur.com/DeLCZdV

在这种情况下,如果我删除查询行:

在 users.category_fk = categories.category 上的 INNER JOIN 类别

DataTable 返回所有数据,但显示类别列 ID 而不是类别名称。下图可以说明这一点:

https://imgur.com/KpsBsiF

但如果我重新包含:

在 users.category_fk = categories.categoryID 上的 INNER JOIN 类别

DataTables 再次显示以下错误:

DataTables 警告:表 id=user_data - JSON 响应无效。有关此错误的更多信息,请参阅http://datatables.net/tn/1

我看到的是,当我只包含一个 INNER JOIN 查询时,DataTable 会显示所有数据,但如果我再包含一个 INNER JOIN,即使包含相应的子数组,DataTable 也会返回无效的 JSON 响应。

$sub_array[] = $row["type"]; $sub_array[] = $row["category"];

在这种情况下,我可以做些什么来改进此代码以显示名称而不是 ID?

【问题讨论】:

【参考方案1】:

如果您只想拥有 1 个表,您可以将 type_service 和类似的类别结合起来

type_service_categories

标识 |类型 |名字

其中类型是服务或类别,名称是服务类型或类别名称

...但这不会解决您的问题,因为无论如何您都必须在查询中编写 2 个内部连接语句。

您的错误可能来自 $result = $statement->fetchAll();

你能发布 db.php 吗?或者你可以试试:

foreach($row as $rkey => $rvalue)
    $sub_array[] = $row[$rkey];

查看调用 fetchAll() 函数时查询返回的字段或它们是如何获取和返回的。

或者尝试 chrome 中的开发者选项来准确查看 json 错误。

【讨论】:

你好。我的 db.php 是: ... ... 在 chrome 上我可以看到这个错误: ... 注意:未定义的索引:在 C:\xampp\htdocs\site\fetch.php 中绘制第 54 行 "draw":0,"recordsTotal":0 ,"recordsFiltered":1,"data":[] .... 第 54 行有一个变量调用输出数组。 试试这个:首先:$sub_array = array(); $sub_array[] = $row["first_name"]; $sub_array[] = $row["last_name"]; $sub_array[] = $row["type"]; $sub_array[] = $row["category"]; 和 $data=$sub_array。或者你可以试试 $data=$result;也许你在 $row 索引键上有错误。 你好@JustAClue。感谢您的支持。我发现了问题。我从 users 表中删除了关系表(type_fk 和 category_fk)。在 index.php 文件中,它有一个将数据插入用户表的 Ajax 代码。我插入了一个 HTML 选择以通过准备好的语句显示选项,因此,用户表接收类型和类别 ID,并在 fetch.php 文件显示类型和类别名称上查询 INNER JOIN,而不是各自的 ID。

以上是关于如何使用 INNER JOIN 改进我的 php sub_array 代码以在 DataTables 上显示数据?的主要内容,如果未能解决你的问题,请参考以下文章

SQL:如何使用 CASE 提高 INNER JOIN 的性能

如何使用多个 INNER JOIN 加快查询速度

如何在 C# 中使用特定的 INNER JOIN 查询和条件制作 Crystal Report

INNER JOIN LIMIT 1 使用分页

INNER JOIN 和 ANTI JOIN 有啥区别

如何将 SQL Inner Join、Group By 转换为 Linq?