บทนำ: SQLite Aggregate Function MAX()
MAX() หาค่าสูงสุดของคอลัมน์ ใช้ได้กับตัวเลข วันที่ ข้อความ (เปรียบเทียบ Lexicographic)
ตัวอย่าง: หาเงินเดือนสูงสุด (MAX Salary)
ขั้นตอนที่ 1-3: โปรเจกต์, Layout, MainActivity
โครงสร้างเดียวกับตัวอย่าง SQLite ก่อนหน้า
ขั้นตอนที่ 4: DatabaseHelper.java - ใช้ MAX()
public ArrayList<String> getAllContacts() {
SQLiteDatabase db = this.getReadableDatabase();
ArrayList<String> array_list = new ArrayList<>();
// MAX(salary) หาค่าสูงสุด
Cursor res = db.rawQuery(
"SELECT (id || ' : ' || name || ' : ' || MAX(salary) || ' : ' || datetime) AS fullname " +
"FROM " + CONTACTS_TABLE_NAME,
null
);
res.moveToFirst();
while (!res.isAfterLast()) {
array_list.add(res.getString(res.getColumnIndex("fullname")));
res.moveToNext();
}
return array_list;
}
คำอธิบาย MAX() พฤติกรรมสำคัญ
ไม่มี GROUP BY
- คืนค่า 1 แถวของตารางทั้งหมด
- คอลัมน์อื่น (id, name, datetime) มาจากแถวที่ SQLite อ่านได้ก่อน (ไม่ได้รับประกัน)
ใช้กับ GROUP BY (แนะนำ)
-- เงินเดือนสูงสุดของแต่ละคน
SELECT name, MAX(salary) FROM SalaryDetails GROUP BY name;
-- เงินเดือนสูงสุดแต่ละเดือน
SELECT strftime('%Y-%m', datetime) as month, MAX(salary)
FROM SalaryDetails GROUP BY month;
⚠️ ข้อควรระวังสำคัญ: Salary เป็น TEXT
ตัวอย่างเก็บ salary เป็น TEXT → MAX() เปรียบเทียบแบบ String
'9000' > '10000' = true(เพราะ '9' > '1') → ผิดพลาด!- แก้ไข:
MAX(CAST(salary AS REAL))หรือเปลี่ยน Schema เป็น INTEGER/REAL
การใช้ CAST แก้ไขปัญหา
Cursor res = db.rawQuery(
"SELECT (id || ' : ' || name || ' : ' || MAX(CAST(salary AS REAL)) || ' : ' || datetime) AS fullname " +
"FROM " + CONTACTS_TABLE_NAME,
null
);
รวม MIN/MAX ในคิวรี่เดียว
SELECT
MIN(CAST(salary AS REAL)) as min_salary,
MAX(CAST(salary AS REAL)) as max_salary,
AVG(CAST(salary AS REAL)) as avg_salary
FROM SalaryDetails;
ผลลัพธ์
ListView แสดง 1 แถว: ข้อมูลพร้อมเงินเดือนสูงสุด (หากเก็บเป็นตัวเลขจะถูกต้อง)