본문으로 건너뛰기

เนื้อหาภาษาไทย / 태국어 콘텐츠

시스템 가이드 검수 완료된 콘텐츠

การใช้ PDO กับ Subquery

บทความนี้อธิบายถึงการใช้งาน Subquery ใน SQL ร่วมกับ PDO เพื่อดึงข้อมูลที่ซับซ้อน โดย Subquery คือ Query ที่ซ้อนอยู่ภายใน Query หลัก และสามารถใช้ใน WHERE หรือ SE...

การใช้ PDO กับ Subquery

ในบทความนี้ เราจะมาเรียนรู้วิธีการใช้ Subquery ใน SQL ร่วมกับ PDO เพื่อดึงข้อมูลที่ซับซ้อนยิ่งขึ้น Subquery คือ Query ที่ซ้อนอยู่ภายใน Query อีกทีหนึ่ง ทำให้เราสามารถดึงข้อมูลโดยอ้างอิงจากผลลัพธ์ของ Query อื่นได้

Subquery คืออะไร?

Subquery หรือ Inner Query คือ SELECT statement ที่ฝังอยู่ภายใน SQL statement หลัก Subquery จะถูก execute ก่อน SQL statement หลัก และผลลัพธ์ของ Subquery จะถูกนำไปใช้ในการ execute SQL statement หลัก

Subquery สามารถปรากฏในหลายส่วนของ SQL statement หลัก เช่น

  • WHERE clause
  • SELECT clause
  • FROM clause (น้อยครั้งที่จะใช้)

ในบทความนี้ เราจะเน้นการใช้งาน Subquery ใน WHERE clause และ SELECT clause เป็นหลัก

การเขียน Subquery

รูปแบบการเขียน Subquery พื้นฐานคือ:

SELECT column1, column2
FROM table_name
WHERE column3 IN (SELECT column3 FROM another_table WHERE condition);

ในตัวอย่างนี้ Subquery คือ (SELECT column3 FROM another_table WHERE condition) ซึ่งจะถูก execute ก่อน และผลลัพธ์ที่ได้จะถูกนำไปใช้ใน WHERE clause ของ Query หลัก

การใช้ Subquery ใน WHERE Clause

Subquery ใน WHERE clause มักถูกใช้เพื่อกรองข้อมูลโดยอ้างอิงจากผลลัพธ์ของ Query อื่น ตัวอย่างเช่น เราต้องการดึงข้อมูลผู้ใช้ทั้งหมดที่ทำการสั่งซื้อ (order) อย่างน้อยหนึ่งครั้ง เราสามารถทำได้ดังนี้:

SELECT *
FROM users
WHERE id IN (SELECT user_id FROM orders);

ในตัวอย่างนี้ Subquery (SELECT user_id FROM orders) จะดึง `user_id` ทั้งหมดจากตาราง `orders` จากนั้น Query หลักจะดึงข้อมูลผู้ใช้ทั้งหมดที่มี `id` ตรงกับ `user_id` ที่ได้จาก Subquery

ตัวอย่างการใช้งานจริง:

สมมติว่าเรามีตาราง `products` และ `orders` โดย `orders` มี column `product_id` ที่อ้างอิงไปยัง `id` ของ `products` เราต้องการดึงข้อมูลสินค้าทั้งหมดที่ถูกสั่งซื้ออย่างน้อย 5 ครั้ง:

SELECT *
FROM products
WHERE id IN (
    SELECT product_id
    FROM orders
    GROUP BY product_id
    HAVING COUNT(product_id) >= 5
);

PHP Code (PDO):

<?php
try {
    $pdo = new PDO("mysql:host=localhost;dbname=your_database", "username", "password");
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $sql = "SELECT *
            FROM products
            WHERE id IN (
                SELECT product_id
                FROM orders
                GROUP BY product_id
                HAVING COUNT(product_id) >= 5
            )";

    $stmt = $pdo->query($sql);

    if ($stmt->rowCount() > 0) {
        echo "<h3>สินค้าที่ถูกสั่งซื้ออย่างน้อย 5 ครั้ง:</h3>";
        echo "<ul>";
        while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
            echo "<li>" . $row["name"] . " (ID: " . $row["id"] . ")</li>";
        }
        echo "</ul>";
    } else {
        echo "<p>ไม่มีสินค้าที่ถูกสั่งซื้ออย่างน้อย 5 ครั้ง</p>";
    }

} catch (PDOException $e) {
    echo "Connection failed: " . $e->getMessage();
}
?>

คำอธิบาย Code:

  1. เราสร้าง PDO connection ไปยังฐานข้อมูล
  2. เราสร้าง SQL query ที่ใช้ Subquery ใน WHERE clause
  3. เรา execute query ด้วย $pdo->query($sql)
  4. เรา loop ผ่านผลลัพธ์ที่ได้และแสดงข้อมูลสินค้า
  5. เราจัดการ exception ในกรณีที่เกิดข้อผิดพลาดในการเชื่อมต่อหรือ query

การใช้ Subquery ใน SELECT Clause

Subquery ใน SELECT clause มักถูกใช้เพื่อดึงข้อมูลเพิ่มเติมที่เกี่ยวข้องกับแต่ละ record ใน Query หลัก ตัวอย่างเช่น เราต้องการดึงข้อมูลผู้ใช้แต่ละคนพร้อมกับจำนวน order ที่พวกเขาเคยทำ เราสามารถทำได้ดังนี้:

SELECT
    users.*,
    (SELECT COUNT(*) FROM orders WHERE user_id = users.id) AS order_count
FROM users;

ในตัวอย่างนี้ Subquery (SELECT COUNT(*) FROM orders WHERE user_id = users.id) จะถูก execute สำหรับแต่ละ row ในตาราง `users` และจะ return จำนวน order ที่ `user_id` ตรงกับ `users.id` ผลลัพธ์ที่ได้จะถูกแสดงเป็น column ชื่อ `order_count`

ตัวอย่างการใช้งานจริง:

สมมติว่าเรามีตาราง `users` และ `orders` เหมือนเดิม เราต้องการดึงข้อมูลผู้ใช้แต่ละคนพร้อมกับวันที่ order ล่าสุดของพวกเขา:

SELECT
    users.*,
    (SELECT MAX(order_date) FROM orders WHERE user_id = users.id) AS last_order_date
FROM users;

PHP Code (PDO):

<?php
try {
    $pdo = new PDO("mysql:host=localhost;dbname=your_database", "username", "password");
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $sql = "SELECT
                users.*,
                (SELECT MAX(order_date) FROM orders WHERE user_id = users.id) AS last_order_date
            FROM users";

    $stmt = $pdo->query($sql);

    if ($stmt->rowCount() > 0) {
        echo "<h3>ข้อมูลผู้ใช้พร้อมวันที่ Order ล่าสุด:</h3>";
        echo "<table border='1'>";
        echo "<tr><th>ID</th><th>Name</th><th>Email</th><th>Last Order Date</th></tr>";
        while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
            echo "<tr>";
            echo "<td>" . $row["id"] . "</td>";
            echo "<td>" . $row["name"] . "</td>";
            echo "<td>" . $row["email"] . "</td>";
            echo "<td>" . $row["last_order_date"] . "</td>";
            echo "</tr>";
        }
        echo "</table>";
    } else {
        echo "<p>ไม่มีข้อมูลผู้ใช้</p>";
    }

} catch (PDOException $e) {
    echo "Connection failed: " . $e->getMessage();
}
?>

คำอธิบาย Code:

  1. เราสร้าง PDO connection ไปยังฐานข้อมูล
  2. เราสร้าง SQL query ที่ใช้ Subquery ใน SELECT clause
  3. เรา execute query ด้วย $pdo->query($sql)
  4. เรา loop ผ่านผลลัพธ์ที่ได้และแสดงข้อมูลผู้ใช้พร้อมวันที่ Order ล่าสุด
  5. เราจัดการ exception ในกรณีที่เกิดข้อผิดพลาดในการเชื่อมต่อหรือ query

ข้อผิดพลาดที่พบบ่อยในการใช้ Subquery

  • Performance: Subquery อาจทำให้ Query ช้าลง โดยเฉพาะอย่างยิ่งถ้า Subquery มีความซับซ้อนหรือ return ข้อมูลจำนวนมาก ควรพิจารณาใช้ JOIN statement แทนถ้าเป็นไปได้
  • Correlated Subquery: Correlated Subquery คือ Subquery ที่อ้างอิงถึง column จาก Query หลัก Correlated Subquery อาจทำให้ Query ช้าลงมาก เนื่องจาก Subquery จะถูก execute สำหรับแต่ละ row ใน Query หลัก
  • Subquery Returns More Than One Row: Subquery ที่ใช้ใน WHERE clause ซึ่งใช้ operator เช่น `=`, `!=`, `>`, `<` ต้อง return เพียง row เดียวเท่านั้น ถ้า Subquery return หลาย row จะเกิด error ควรใช้ operator `IN`, `ANY`, หรือ `ALL` แทน

สรุป

Subquery เป็นเครื่องมือที่มีประโยชน์สำหรับการดึงข้อมูลที่ซับซ้อน แต่ควรใช้อย่างระมัดระวังเพื่อหลีกเลี่ยงปัญหาด้าน Performance ในบทความนี้ เราได้เรียนรู้วิธีการใช้ Subquery ใน WHERE clause และ SELECT clause พร้อมทั้งยกตัวอย่างการใช้งานจริงและข้อผิดพลาดที่พบบ่อย ในบทความถัดไป เราจะเรียนรู้เกี่ยวกับการใช้ PDO กับ Stored Procedure

Office.in.th Custom Service

이 구조를 바탕으로 시스템을 개발하거나 맞춤 변경하고 싶으신가요?

Office.in.th는 엔터프라이즈 웹 애플리케이션, API 연동, 공공/민간 업무 관리 시스템을 설계·개발하며 장기 지원을 제공합니다.

소프트웨어 개발 서비스 보기