ภาพรวม
SQLite เป็นฐานข้อมูล SQL แบบ Open Source ที่เก็บข้อมูลในไฟล์ข้อความบนอุปกรณ์ Android มี SQLite ในตัว รองรับฟีเจอร์ฐานข้อมูลเชิงสัมพันธ์ครบถ้วน
ตัวอย่างนี้สาธิตการใช้ ORDER BY ใน SQLite เพื่อจัดเรียงข้อมูลตามลำดับที่ต้องการ (Ascending/Descending)
ขั้นตอนการสร้าง
ขั้นตอนที่ 1: สร้างโปรเจกต์ใหม่
Android Studio → File → New Project → กรอกรายละเอียด
ขั้นตอนที่ 2: จัดรูปแบบหน้าจอ (res/layout/activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">
<EditText
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="ป้อนชื่อ" />
<EditText
android:id="@+id/salary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="numberDecimal"
android:hint="ป้อนเงินเดือน" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/save"
android:text="บันทึก"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/refresh"
android:text="รีเฟรช"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/update"
android:text="อัปเดต"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
ขั้นตอนที่ 3: เขียนโค้ด MainActivity (src/MainActivity.java)
package com.example.andy.myapplication;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
Button save, refresh;
EditText name, salary;
private ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final DatabaseHelper helper = new DatabaseHelper(this);
final ArrayList<String> arrayList = helper.getAllContacts();
name = findViewById(R.id.name);
salary = findViewById(R.id.salary);
listView = findViewById(R.id.listView);
final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(
this, android.R.layout.simple_list_item_1, arrayList);
listView.setAdapter(arrayAdapter);
findViewById(R.id.refresh).setOnClickListener(v -> {
arrayList.clear();
arrayList.addAll(helper.getAllContacts());
arrayAdapter.notifyDataSetChanged();
listView.invalidateViews();
listView.refreshDrawableState();
});
findViewById(R.id.save).setOnClickListener(v -> {
String nameStr = name.getText().toString().trim();
String salaryStr = salary.getText().toString().trim();
if (!nameStr.isEmpty() && !salaryStr.isEmpty()) {
if (helper.insert(nameStr, salaryStr)) {
Toast.makeText(this, "บันทึกสำเร็จ", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, "บันทึกไม่สำเร็จ", Toast.LENGTH_LONG).show();
}
} else {
name.setError("กรุณาป้อนชื่อ");
salary.setError("กรุณาป้อนเงินเดือน");
}
});
}
}
ขั้นตอนที่ 4: สร้าง DatabaseHelper (src/DatabaseHelper.java)
package com.example.andy.myapplication;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import java.io.IOException;
import java.util.ArrayList;
class DatabaseHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "salaryDatabase5";
public static final String CONTACTS_TABLE_NAME = "SalaryDetails";
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
try {
db.execSQL("CREATE TABLE " + CONTACTS_TABLE_NAME +
"(id INTEGER PRIMARY KEY, name TEXT, salary TEXT, datetime DEFAULT CURRENT_TIMESTAMP)");
} catch (SQLiteException e) {
try { throw new IOException(e); }
catch (IOException e1) { e1.printStackTrace(); }
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + CONTACTS_TABLE_NAME);
onCreate(db);
}
public boolean insert(String name, String salary) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("name", name);
values.put("salary", salary);
db.replace(CONTACTS_TABLE_NAME, null, values);
return true;
}
public ArrayList<String> getAllContacts() {
SQLiteDatabase db = this.getReadableDatabase();
ArrayList<String> arrayList = new ArrayList<>();
// เรียงตามชื่อ A-Z (ASC - Default)
Cursor res = db.rawQuery(
"SELECT * FROM " + CONTACTS_TABLE_NAME + " ORDER BY name ASC", null);
res.moveToFirst();
while (!res.isAfterLast()) {
arrayList.add(res.getString(res.getColumnIndex("name")));
res.moveToNext();
}
res.close();
return arrayList;
}
public boolean update(String name, String salary) {
SQLiteDatabase db = this.getWritableDatabase();
db.execSQL("UPDATE " + CONTACTS_TABLE_NAME +
" SET name = '" + name + "', salary = '" + salary + "'");
return true;
}
public boolean delete() {
SQLiteDatabase db = this.getWritableDatabase();
db.execSQL("DELETE FROM " + CONTACTS_TABLE_NAME);
return true;
}
}
การทดสอบ
รันแอปพลิเคชัน เพิ่มข้อมูลหลายรายการ แล้วกด Refresh

ผลลัพธ์: แสดงชื่อเรียงลำดับ ASC (A → Z)

ความรู้เพิ่มเติมเกี่ยวกับ ORDER BY
รูปแบบต่างๆ ของ ORDER BY
-- ASC: น้อยไปมาก (Default) ORDER BY name ASC ORDER BY salary ASC -- DESC: มากไปน้อย ORDER BY name DESC ORDER BY salary DESC -- หลายคอลัมน์ (เรียงคอลัมน์แรกก่อน แล้วค่อยคอลัมน์ถัดไป) ORDER BY department ASC, salary DESC, name ASC -- ใช้กับ Expression/Function ORDER BY LENGTH(name) DESC -- เรียงตามความยาวข้อความ ORDER BY LOWER(name) ASC -- เรียงไม่สนใจ Case (Case-insensitive) ORDER BY CAST(salary AS REAL) DESC -- เรียงตัวเลขใน String column ORDER BY date_column DESC -- เรียงวันที่
NULL Handling ใน ORDER BY
-- SQLite Default: NULLs FIRST สำหรับ ASC, NULLs LAST สำหรับ DESC ORDER BY name ASC -- NULL อยู่บนสุด ORDER BY name DESC -- NULL อยู่ท้ายสุด -- SQLite 3.38+ รองรับ NULLS FIRST/LAST ORDER BY name ASC NULLS LAST -- NULL อยู่ท้าย ORDER BY name DESC NULLS FIRST -- NULL อยู่หน้า
Performance Optimization
- Index: สร้าง Index บนคอลัมน์ที่ ORDER BY บ่อย
CREATE INDEX idx_salary_details_name ON SalaryDetails(name); CREATE INDEX idx_salary_details_salary ON SalaryDetails(salary); -- Compound Index สำหรับ ORDER BY หลายคอลัมน์ CREATE INDEX idx_dept_salary ON SalaryDetails(department, salary DESC);
- Covering Index: รวมคอลัมน์ที่ SELECT ด้วย
CREATE INDEX idx_covering ON SalaryDetails(name, salary, datetime); -- Query นี้จะใช้ Index Only Scan (เร็วมาก) SELECT name, salary FROM SalaryDetails ORDER BY name;
การใช้ LIMIT กับ ORDER BY
-- Top 10 SELECT * FROM table ORDER BY score DESC LIMIT 10; -- Pagination SELECT * FROM table ORDER BY created_at DESC LIMIT 20 OFFSET 0; -- Page 1 SELECT * FROM table ORDER BY created_at DESC LIMIT 20 OFFSET 20; -- Page 2
Collation (การเรียงตามภาษา/Locale)
-- Built-in Collations ORDER BY name COLLATE BINARY -- ตาม Byte Value (Default) ORDER BY name COLLATE NOCASE -- ไม่สนใจพิมพ์เล็ก/ใหญ่ ORDER BY name COLLATE RTRIM -- ตัด Trailing Space -- ภาษาไทย: ต้องใช้ ICU Collator (Custom Collation) -- ใน Android ใช้ผ่าน java.text.Collator กับ CursorWrapper
Best Practices
- ระบุ ASC/DESC ชัดเจน เพื่อความอ่านง่าย
- สร้าง Index บนคอลัมน์ที่ใช้ ORDER BY บ่อย
- ใช้ LIMIT เพื่อจำกัดผลลัพธ์ (Performance)
- หลีกเลี่ยง ORDER BY RAND() บนตารางใหญ่ (ใช้วิธี Random Sampling แทน)
- ใน Room: ใช้ @Query("SELECT * FROM table ORDER BY name ASC")
- ใช้ Parameterized Query สำหรับ Dynamic ORDER BY (Validate Column Name ก่อน)
สรุป
คำสั่ง ORDER BY ใน SQLite ใช้จัดเรียงผลลัพธ์การ Query ใช้ร่วมกับ Index จะได้ Performance ดีที่สุด สำหรับภาษาไทยควรพิจารณา Custom Collation หรือจัดเรียงใน Application Layer แทน