PHP กับการเชื่อมตารางหลายตารางโดยไม่ใช้ JOIN
ในการเขียนโปรแกรม PHP กับ MySQL บางครั้งการ JOIN แม้จะทำ INDEX ไปแล้วแต่ก็ยังมีโอกาสทำงานช้าได้ ซึ่งจากบทความก่อนหน้านั้น ผมได้สาธิตวิธีการเขียนโปรแกรมเชื่อมต่อฐานข้อมูล MySQL หลายตารางด้วยคำสั่ง JOIN ไว้ในบทความ "การทำ Index ให้ MySQL Database เพื่อเพิ่มความเร็ว" จะเห็นว่าเราสามารถเพิ่มความเร็วให้ได้อย่างดีทีเดียว
แต่การเขียนโปรแกรมดังในวิดีโอนี้ จะเป็นการใช้ Array เก็บข้อมูลจากฐานข้อมูลไว้เปรียบเทียบรหัสที่ตรงกัน เพื่อดึงชื่อจากตารางอื่นมาแสดง ซึ่งก็มีข้อจำกัดเรื่องจำนวนเรคอร์ดหรือแถวของตารางที่จะดึงข้อมูลมาใส่ใน Array เพราะถ้าข้อมูลเยอะและมีการเปลี่ยนแปลงตลอดเวลา การเขียนโปรแกรม PHP โดยเก็บไว้ในอาร์เรย์ทั้งหมด ก็คงเป็นเรื่องยาก
$allProduct = array();
$allCategoryId = array();
ดังนั้นตัวแปรทั้งสองตัวด้านบนนี้ จึงต้องเก็บเฉพาะข้อมูลของรายการที่เกี่ยวข้องเท่านั้นด้วยการค้นหาตาราง product โดยคัดเอาเฉพาะที่มีอยู่ในรายการเท่านั้น IN()
$allCategory = array();แต่การใช้กับตาราง category จะต่างกัน เพราะในตารางนี้เป็นข้อมูลหลัก ที่นานๆจะเปลี่ยนแปลงที หรือต่อให้เปลี่ยนแปลงยังไงก็ไม่เกินร้อยเรคอร์ด หรือไม่เกินพัน ก็เป็นเรื่องง่ายที่จะจับข้อมูลทั้งหมดใส่ใน Array ไปเลย
สำหรับ Code PHP ในตัวอย่างมีดังต่อไปนี้
[ PHP Code ]
<?php
$page_title = 'เชื่อมข้อมูลหลายตารางแบบไม่ใช้ INNERT/LEFT JOIN';
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>PHP สำหรับผู้เริ่มต้น : <?php echo $page_title;?></title>
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css">
<style>
body{
font-family : 'TH sarabunPSK';
padding : 10px;
font-size : 18pt;
}
</style>
</head>
<body>
<?php
$db_config=array(
"host"=>"localhost", // กำหนด host
"user"=>"tobedev", // กำหนดชื่อ user
"pass"=>"abcd.1234", // กำหนดรหัสผ่าน
"dbname"=>"tobedev_product_cost", // กำหนดชื่อฐานข้อมูล
"charset"=>"utf8" // กำหนด charset
);
$mysqli = @new mysqli($db_config["host"], $db_config["user"], $db_config["pass"], $db_config["dbname"]);
if(mysqli_connect_error()) {
die('Connect Error (' . mysqli_connect_errno() . ') '. mysqli_connect_error());
exit;
}
if(!$mysqli->set_charset($db_config["charset"])) { // เปลี่ยน charset เป้น utf8 พร้อมตรวจสอบการเปลี่ยน
printf("Error loading character set utf8: %sn", $mysqli->error); // ถ้าเปลี่ยนไม่ได้
}
//ดึงข้อมูลการขาย ซึ่งเป็นข้อมูลหลักที่ต้องการ แต่จะได้แค่ไอดี product ยังขาดชื่อและหมวดหมู่
$sql = "SELECT * FROM `product_sales`
WHERE sale_date BETWEEN '2017-08-01' AND '2017-08-31'
GROUP BY product_id
ORDER BY `product_id` ";
$result = $mysqli->query($sql); // ทำการ query คำสั่ง sql
$data_list = array();
while($rs = $result->fetch_assoc()){ // วนลูปแสดงข้อมูล
$data_list[] = $rs;
}
//เริ่มสร้าง Array เก็บชื่อหมวดหมู่และสินค้า
// เก็บรายชื่อ Category ทั้งหมด
$sql = "SELECT * FROM `category`";
$result = $mysqli->query($sql);
$allCategory = array();
while($rs = $result->fetch_assoc()){
$allCategory[$rs['id']] = $rs['name'];
}
//ดึงข้อมูลรหัสสินค้า จาก Array ทั้งหมด
$productAllId = array_column($data_list, 'product_id');
//สร้างรหัสต่อเนื่องเพื่อนำไปใช้กับฟังก์ชั่น IN() ใน MySQL
// ที่ต้องใช้ IN() เพื่อกรองแค่ข้อมูลที่ต้องการเท่านั้น
// หากข้อมูลใน product นานๆเพิ่มที่ หรือจำกัดไม่มาก จะดึงทั้งหมดก็ได้
//แล้วแต่ว่าแบบไหนจะทำงานเร็วกว่ากัน
$in_id = implode($productAllId, ',');
$sql = "SELECT id, name, category_id
FROM `product`
WHERE id IN ($in_id)";
$result = $mysqli->query($sql);
$allProduct = array();
$allCategoryId = array();
//วนลูปเก็บชื่อ และหมวดหมู่สินค้า
while($rs = $result->fetch_assoc()){
$allProduct[$rs['id']] = $rs['name'];
$allCategoryId[$rs['id']] = $rs['category_id'];
}
//echo '<pre>',print_r($allProduct, true),'</pre>';
//ปิดการเชื่อมต่อฐานข้อมูล
$mysqli->close();
?>
<h1><?php echo $page_title;?></h1>
<div>
ตารางที่ 1 <b>category</b>, ตารางที่ 2 <b>product</b>, ตารางที่ 3 <b>product_sales</b> (ตารางที่ต้องการผลลัพธ์)
</div>
<table class="table table-bordered">
<thead>
<tr>
<th>Product ID</th>
<th>Product Name</th>
<th>Category</th>
</tr>
</thead>
<tbody>
<?php
if(!empty($data_list)){
foreach($data_list as $row){
$product_id = $row['product_id'];
//ตรวจสอบว่า product_id ตรงกับค่าใน Array หรือไม่ ถ้าตรงให้ดึงออกมาใช้
$cate_id = isset($allCategoryId[$product_id]) ? $allCategoryId[$product_id] : '';
$category_name = isset($allCategory[$cate_id]) ? $allCategory[$cate_id] : '';
$product_name = isset($allProduct[$product_id]) ? $allProduct[$product_id] : '';
?>
<tr>
<td><?php echo $product_id;?></td>
<td><?php echo $product_name;?></td>
<td><?php echo $category_name;?></td>
</tr>
<?php
}
}
?>
</tbody>
</table>
<script src="jquery/jquery.min.js"></script>
<script src="jquery-ui/jquery-ui.min.js"></script>
<script src="bootstrap/js/bootstrap.min.js"></script>
</body>
</html>
[ SQL สร้างฐานข้อมูล ]
บทความที่คล้ายกัน
PHP กับจัดการฐานข้อมูลหมวดหมู่สินค้า MySQL แบบใช้ตารางเพียงตารางเดียวเท่านั้น
PHP CI MANIA - PHP Code Generator
โปรแกรมช่วยสร้างโค้ด ลดเวลาการเขียนโปรแกรม เขียนโปรแกรมง่ายและสะดวกขึ้น
สนใจสั่งซื้อราคาสุดคุ้ม >> http://fastcoding.phpcodemania.com/
อ้างอิง
array_column — Return the values from a single column in the input array
http://php.net/manual/en/function.array-column.php
implode — Join array elements with a string
http://php.net/manual/en/function.implode.php
MySQL WHERE IN ()
https://stackoverflow.com/questions/9736284/mysql-where-in
มาใช้ mysqli แทน mysql แบบเดิม ใน php กันอย่างง่าย
https://www.ninenik.com/มาใช้_mysqli_แทน_mysql_แบบเดิม_ใน_php_กันอย่างง่าย-527.html
มาใช้ mysqli แทน mysql แบบเดิม ใน php กันอย่างง่าย
https://www.ninenik.com/มาใช้_mysqli_แทน_mysql_แบบเดิม_ใน_php_กันอย่างง่าย-527.html
ความคิดเห็น
แสดงความคิดเห็น