24 January 2013

SQLite in Android - การ Query ในฐานข้อมูล SQLite

Updated on
คราวนี้จะเป็นเรื่องของการใช้ Query ใน Cursor กันบ้างละ
เพราะยังมีหลายคนที่ใช้ Query และ Cursor ไม่เป็นกันอยู่พอสมควร
ซึ่งเอาจริงๆแล้วทั้งสองอย่างนี้ ก็ไม่ได้มีความซับซ้อนอะไรมากมาย
แต่เพราะไม่มีใครอธิบายการใช้งานให้กระจ่างกันซะมากกว่า
เจ้าของบล็อกก็เลยมาหยิบเรื่องพื้นฐานแบบนี้มาอธิบายให้ฟัง

สำหรับ Cursor มีไว้สำหรับเลือกแถว (Row) ในฐานข้อมูล
เพื่อเจาะจงว่าผู้ที่หลงเข้ามาอ่านจะเลือกดึงข้อมูลในแถวไหน
ก่อนอื่นสมมติว่ามีฐานข้อมูลอยู่แล้ว โดยมีรายละเอียดตามนี้

ชื่อฐานข้อมูล Fresh
ชื่อตาราง MyProduct 

ส่วนข้อมูลทั้งหมดที่เจ้าของบล็อกใช้ก็ดูในภาพได้เลย


อันนี้เป็นฐานข้อมูลเริ่มต้นที่เจ้าของบล็อกเตรียมไว้นะ
ให้ยืดข้อมูลนี้เป็นหลัก เพราะจะดึงข้อมูลบางส่วนไปใช้


การใช้ Select

ทีนี้ก็มาดูการใช้งาน Cursor ซึ่งก่อนอื่นก็ต้องเปิดใช้ฐานข้อมูล
แล้วค่อยดึงข้อมูลจากฐานข้อมูลมาเก็บไว้ใน Cursor อีกที
SELECT * FROM MyProduct
ทีนี้มาดูแต่ในส่วนของคำสั่ง SQL กันก่อนเลยละกันนะ


เวลาใช้คำสั่งใน rawQuery ก็ใช้คำสั่งแบบนี้ได้เลย
String TABLE_NAME = "MyProduct"; mHelper = new Database(this); mDb = mHelper.getWritableDatabase(); Cursor mCursor = mDb.rawQuery("SELECT * FROM " + TABLE_NAME, null);
จะเห็นว่าการดึงข้อมูลจากฐานข้อมูลจะใช้คำสั่ง rawQuery
ซึ่งจะใช้คำสั่ง SQL ในการดึงข้อมูลมาเก็บใน Cursor นั่นแหละ

คำสั่งนี้สรุปได้ว่าดึงข้อมูลทุกตัวที่อยู่ในตารางที่ชื่อว่า MyProduct
โดยข้อมูลทั้งหมดนี้จะถูกนำมาเก็บไว้ในตัวแปร mCursor ที่สร้างไว้



อันนี้คือกรณีที่เลือกข้อมูลในฐานข้อมูลทุกคอลัมน์นะ
ถ้าต้องการดึงแค่บางคอลัมน์ก็ใช้คำสั่งตามนี้แทนเลย
SELECT name,type,amount FROM MyProduct


คำสั่งดังกล่าวเป็นการดึงข้อมูลจากตาราง MyProduct
โดยจะดึงข้อมูลจากคอลัมน์ name, type และ amount เท่านั้น
เวลาใช้คำสั่งดังกล่าวในแอนดรอยด์ก็จะได้ตามนี้เลย
String TABLE_NAME = "MyProduct"; String COL_NAME = "name"; String COL_TYPE = "type"; String COL_AMOUNT = "amount"; Cursor mCursor = mDb.rawQuery("SELECT " + COL_NAME + "," + COL_TYPE + "," + COL_AMOUNT + " FROM " + TABLE_NAME, null);

ข้อมูลที่ดึงมาเก็บไว้ใน mCursor ก็จะมีแค่คอลัมน์ที่เลือกไว้


ขอต่อเรื่องการเลือกดึงข้อมูลเฉพาะคอลัมน์ต่ออีกหน่อยละกัน
จะได้เป็นตัวอย่างหลายๆแบบให้ผู้ที่หลงเข้ามาอ่านเข้าใจมากขึ้น
ทีนี้ก็ลองเลือกดึงข้อมูลเฉพาะคอลัมน์แบบอื่นๆดูบ้าง
SELECT _id,name FROM MyProduct

พอเขียนลงในแอนดรอยด์ก็จะได้คำสั่งออกมาเป็นแบบนี้
String TABLE_NAME = "MyProduct"; String COL_ID = "_id"; String COL_NAME = "name"; Cursor mCursor = mDb.rawQuery("SELECT " + COL_ID + "," + COL_NAME + " FROM " + TABLE_NAME, null);

ข้อมูลในฐานข้อมูลที่ดึงมาเก็บไว้ใน mCursor ก็จะมีดังนี้



ถึงจุดนี้แล้วก็คงเข้าใจแล้วล่ะ แต่ก็ขอต่อเรื่องการดึงข้อมูลนะ
ยังไม่ไปเรื่องการนำข้อมูลมาใช้ ขอเรื่องการดึงข้อมูลให้ครบก่อน


การใช้ Where

ทีนี้ผู้ที่หลงเข้ามาอ่านอาจจะต้องการดึงข้อมูลแค่บางแถว
ก็จะต้องใช้คำสั่ง Where ซึงมีวิธีการใช้คำสั่งตามนี้เลย
SELECT * FROM MyProduct WHERE store='Lotus'


ดังนั้นข้อมูลที่ได้ก็จะเป็นข้อมูลที่คอลัมน์ store เก็บข้อมูลเป็น Lotus
โดยจะดึงทุกคอลัมน์ของข้อมูลในแต่ละแถวที่เลือกไว้ (งงป่าวหว่า)
เวลาใช้คำสั่งในแอนดรอยด์ก็จะใช้คำสั่งตามนี้เลย
String TABLE_NAME = "MyProduct"; String COL_STORE = "store"; Cursor mCursor = mDb.rawQuery("SELECT * FROM " + TABLE_NAME + " WHERE " + COL_STORE + "='Lotus'", null);

ข้อมูลที่ดึงมาเก็บไว้ใน mCursor ก็จะเป็นตามนี้เลย



ลองอีกตัวอย่างหนึ่งละกันเพื่อให้เข้าใจมากขึ้นกว่าเดิม
ทีนี้ลองดึงข้อมูลเฉพาะคอลัมน์และเฉพาะแถวดูบ้าง
SELECT name,type,amount FROM MyProduct WHERE amount=40

สำหรับคำสั่งนี้จะเห็นว่าใส่ amount=40 เลย ไม่ใช่ amount='40'
เพราะว่าฐานข้อมูลนี้ ได้กำหนดคอลัมน์ amount ให้เป็น Integer น่ะ



เวลาใช้คำสั่งในแอนดรอยด์ก็ใช้คำสั่งตามนี้เลย
String TABLE_NAME = "MyProduct"; String COL_NAME = "name"; String COL_TYPE = "type"; String COL_AMOUNT = "amount"; Cursor mCursor = mDb.rawQuery("SELECT " + COL_NAME + "," + COL_TYPE + "," + COL_AMOUNT + " FROM " + TABLE_NAME + " WHERE " + COL_AMOUNT + "=40", null);

ข้อมูลที่ดึงมาเก็บไว้ใน mCursor ก็จะได้ตามนี้เลย



ก็คงเข้าใจกันแล้วล่ะ แต่ก็ขออีกตัวอย่างนึงนะ 5555
คราวนี้จะมาลองอะไรแปลกๆดูกันบ้างละกันนะ
โดยคราวนี้จะดึงข้อมูลจากคอลัมน์ส่วนหนึ่ง
แต่ว่าค้นหาข้อมูลจากคอลัมน์ที่ไม่ได้ดึงกันบ้าง
SELECT _id,name FROM MyProduct WHERE store='Macro'

สำหรับคำสั่งบนแอนดรอยด์ก็จะใช้คำสั่งตามนี้เลย
String TABLE_NAME = "MyProduct"; String COL_NAME = "name"; String COL_TYPE = "type"; String COL_STORE = "store"; Cursor mCursor = mDb.rawQuery("SELECT " + COL_ID + "," + COL_NAME + " FROM " + TABLE_NAME + " WHERE " + COL_STORE + "='Macro'", null);

คราวนี้จะเห็นเจ้าของบล็อกจงใจค้นหาข้อมูลจากคอลัมน์ที่ไม่ได้เลือก
แต่ถึงแม้จะไม่ได้เลือก ข้อมูลที่ดึงมาก็จะค้นหาเฉพาะ Macro อยู่ดี
เพียงแต่ว่าคอลัมน์ที่ดึงมาเก็บไว้ใน mCursor ก็จะมีแค่ส่วนของ _id กับ name


กรอบและตัวหนังสือสีฟ้าไม่เกี่ยวนะ แค่เอามาเป็นภาพประกอบเฉยๆ

ทีนี้มาดูกรณีทีค้นหาคอลัมน์หรือข้อมูลที่มากกว่าหนึ่งแบบดูบ้าง
SELECT * FROM MyProduct WHERE amount=60 OR amount=35

เวลาเขียนบนแอนดรอยด์ก็จะเขียนคำสั่งออกมาตามนี้เลย
String TABLE_NAME = "MyProduct"; String COL_AMOUNT = "amount"; Cursor mCursor = mDb.rawQuery("SELECT * FROM " + TABLE_NAME + " WHERE " + COL_AMOUNT + "=60" + " OR " + COL_AMOUNT + "=35", null);

ถ้ายังจำกันได้ในบทความที่แล้วในเรื่องพื้นฐานของ SQLite
เห็นกันมาบ้างแล้วกับการใช้ And หรือ Or ซึ่ง Query ก็ใช้ได้เช่นกัน
ซึ่งในตัวอย่างนี้ก็คือเลือกข้อมูลทุกคอลัมน์ของตาราง MyProduct
แต่เลือกแถวที่คอลัมน์ amount มีค่าเป็น 60 หรือ 35 เท่านั้น



แต่ถ้าใช้ And ก็ควรเป็นคนละคอลัมน์กันนะ (เหตุผลทาง Logic)
SELECT * FROM MyProduct WHERE type='vegetable' AND amount=35

เวลาเขียนคำสั่งบนแอนดรอยด์ก็ใช้คำสั่งตามนี้เลย
String TABLE_NAME = "MyProduct"; String COL_TYPE = "type"; String COL_AMOUNT = "amount"; Cursor mCursor = mDb.rawQuery("SELECT * FROM " + TABLE_NAME + " WHERE " + COL_TYPE + "='vegetable'" + " AND " + COL_AMOUNT + "=35", null);

จริงๆจะมากกว่าสองเงื่อนไขก็ได้นะ แต่เจ้าของบล็อกขี้เกียจพิม
เดี๋ยวมันจะยาวล้นขอบจอ ก็เลยยกตัวอย่างแค่สองเงื่อนไข
สำหรับตัวอย่างข้างบนนี้ข้อมูลที่ดึงมาเก็บใน mCursor ก็จะเป็นดังนี้



การใช้ Order By


หมดล่ะสำหรับการใช้ Where ทีนี้ก็มาต่อกับเรื่อง Order By บ้าง
ซึ่ง Order By เป็นคำสั่ง SQL ที่เอาไว้เรียงลำดับของข้อมูล
ให้ข้อมูลที่ดึงมาไว้ใน mCursor เรียงตามลำดับตัวอักษรหรือตัวเลข
เรียงได้สองแบบคือ มากไปหาน้อย (DESC) กับ น้อยไปหามาก (ASC)
SELECT * FROM MyProduct ORDER BY amount ASC



เวลาใช้คำสั่งนี้บนแอนดรอยด์ก็จะใช้คำสั่งตามนี้เลย
String TABLE_NAME = "MyProduct"; String COL_AMOUNT = "amount"; Cursor mCursor = mDb.rawQuery("SELECT * FROM " + TABLE_NAME + " ORDER BY " + COL_AMOUNT + " ASC", null);

ข้อมูลที่ดึงมาเก็บไว้ใน mCursor ก็จะเรียงจากน้อยไปหามาก
โดยจะเรียงจากข้อมูลที่อยู่ในคอลัมน์ amount นั่นเอง



ขออีกตัวอย่างหนึ่งละกัน แต่คราวนี้เรียงตามตัวอักษรบ้าง
SELECT name,type FROM MyProduct ORDER BY name DESC

เวลาใช้คำสั่งนี้บนแอนดรอยด์ก็จะใช้คำสั่งตามนี้เลย
String TABLE_NAME = "MyProduct"; String COL_NAME = "name"; String COL_TYPE = "type"; Cursor mCursor = mDb.rawQuery("SELECT " + COL_NAME + "," + COL_TYPE + " FROM " + TABLE_NAME + " ORDER BY " + COL_NAME + " DESC", null);

ข้อมูลที่ดึงมาก็จะมีแค่ name กับ type โดยเรียง name จากมากไปหาน้อย
ซึ่งการเรียงลำดับตัวอักษรจากน้อยไปหามากจะเรียงจาก a-z และ A-Z
และถ้าเรียงจากมากไปหาน้อยก็จะเป็น Z-A และตามด้วย z-a 
จะเห็นว่า a และ A ไม่ได้เรียงต่อกัน ดังนั้นให้ระวังในจุดนี้ด้วยนะ



จะใช้ควบคู่กับ Where ก็ได้เช่นกัน โดยใช้คำสั่ง Order By ต่อท้าย Where
SELECT name,type,amount,store FROM MyProduct 
WHERE store='Big C' ORDER BY name ASC

เวลาใช้คำสั่งนี้บนแอนดรอยด์ก็ใช้คำสั่งตามนี้ได้เลย
String TABLE_NAME = "MyProduct";
String COL_NAME = "name";
String COL_TYPE = "type";
String COL_AMOUNT = "amount";
String COL_STORE = "store";

Cursor mCursor = mDb.rawQuery("SELECT " + COL_NAME + "," + COL_TYPE 
        + "," + COL_AMOUNT + "," + COL_STORE + " FROM " + TABLE_NAME 
        + " WHERE " + COL_STORE + "='Big C'" 
        + " ORDER BY " + COL_NAME + " ASC", null);

ข้อมูลที่ดึงมาเก็บไว้ใน mCursor ก็จะมีคอลัมน์ name, type, amount และ store
โดยจะดึงข้อมูลเฉพาะแถวที่คอลัมน์ store มีข้อมูลเป็น Big C อย่างเดียว
โดยจะเรียงข้อมูลในคอลัมน์ name จากน้อยไปหามาก (ยาวชะมัด)



จบแล้วกับการ Query ข้อมูลจากฐานข้อมูลที่ยาวเหยียด
ผู้ที่หลงเข้ามาอ่านก็ควรจะลองหัดใช้ให้คล่องดูนะ
สำหรับผู้ที่หลงเข้ามาอ่านที่ต้องการดาวน์โหลดโปรแกรมตัวอย่าง
สามารถดาวน์โหลดได้ที่ Database Raw Query [Google Drive]
ไฟล์ตัวอย่างจะมีคำสั่งสั้นๆ อ่านคอมเม้น แล้วทำตามบทความนี้ดู


เสร็จซะที!!!!!!!!!!