Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Android

Cách sử dụng AVG() trong SQLite Android

Giới thiệu

Ví dụ này minh họa cách sử dụng hàm tổng hợp AVG() trong SQLite Android để tính giá trị trung bình của cột số (ví dụ: lương trung bình).

Bước 1: Tạo dự án mới

Mở Android Studio, chọn File → New Project và điền đầy đủ thông tin cần thiết.

Bước 2: Thiết kế giao diện (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"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Nhập tên" />

    <EditText
        android:id="@+id/salary"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Nhập lương"
        android:inputType="numberDecimal" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:id="@+id/save"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Lưu" />

        <Button
            android:id="@+id/refresh"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Tính AVG" />

        <Button
            android:id="@+id/update"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Cập nhật" />

        <Button
            android:id="@+id/delete"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Xóa tất cả" />

    </LinearLayout>

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

Bước 3: MainActivity.java

package com.example.andy.myapplication;

import android.os.Bundle;
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 androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {
    Button save, refresh, update, delete;
    EditText name, salary;
    ListView listView;
    DatabaseHelper helper;
    ArrayAdapter arrayAdapter;
    ArrayList arrayList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        helper = new DatabaseHelper(this);
        arrayList = new ArrayList<>(helper.getAllContacts());
        
        name = findViewById(R.id.name);
        salary = findViewById(R.id.salary);
        listView = findViewById(R.id.listView);
        save = findViewById(R.id.save);
        refresh = findViewById(R.id.refresh);
        update = findViewById(R.id.update);
        delete = findViewById(R.id.delete);

        arrayAdapter = new ArrayAdapter<>(this, 
            android.R.layout.simple_list_item_1, arrayList);
        listView.setAdapter(arrayAdapter);

        delete.setOnClickListener(v -> {
            if (helper.deleteAll()) {
                Toast.makeText(this, "Đã xóa", Toast.LENGTH_LONG).show();
                refreshList();
            } else {
                Toast.makeText(this, "Xóa thất bại", Toast.LENGTH_LONG).show();
            }
        });

        update.setOnClickListener(v -> {
            String n = name.getText().toString().trim();
            String s = salary.getText().toString().trim();
            if (!n.isEmpty() && !s.isEmpty()) {
                if (helper.update(n, s)) {
                    Toast.makeText(this, "Đã cập nhật", Toast.LENGTH_LONG).show();
                    refreshList();
                } else {
                    Toast.makeText(this, "Cập nhật thất bại", Toast.LENGTH_LONG).show();
                }
            } else {
                name.setError("Nhập tên");
                salary.setError("Nhập lương");
            }
        });

        refresh.setOnClickListener(v -> refreshList());

        save.setOnClickListener(v -> {
            String n = name.getText().toString().trim();
            String s = salary.getText().toString().trim();
            if (!n.isEmpty() && !s.isEmpty()) {
                if (helper.insert(n, s)) {
                    Toast.makeText(this, "Đã thêm", Toast.LENGTH_LONG).show();
                    refreshList();
                    name.setText("");
                    salary.setText("");
                } else {
                    Toast.makeText(this, "Thêm thất bại", Toast.LENGTH_LONG).show();
                }
            } else {
                name.setError("Nhập tên");
                salary.setError("Nhập lương");
            }
        });
    }

    private void refreshList() {
        arrayList.clear();
        arrayList.addAll(helper.getAllContacts());
        arrayAdapter.notifyDataSetChanged();
    }
}

Bước 4: 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.SQLiteOpenHelper;
import java.util.ArrayList;

class DatabaseHelper extends SQLiteOpenHelper {
    private static final String DATABASE_NAME = "salaryDatabase5";
    private static final String TABLE_NAME = "SalaryDetails";
    private static final int DATABASE_VERSION = 1;

    DatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        // Dùng REAL hoặc NUMERIC cho số thập phân
        String sql = "CREATE TABLE " + TABLE_NAME + " (" +
            "id INTEGER PRIMARY KEY AUTOINCREMENT, " +
            "name TEXT, " +
            "salary REAL, " +  -- REAL cho số thực (float/double)
            "datetime DEFAULT CURRENT_TIMESTAMP)";
        db.execSQL(sql);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
        onCreate(db);
    }

    boolean insert(String name, String salary) {
        SQLiteDatabase db = getWritableDatabase();
        ContentValues cv = new ContentValues();
        cv.put("name", name);
        try {
            cv.put("salary", Double.parseDouble(salary));
        } catch (NumberFormatException e) {
            cv.put("salary", salary);
        }
        long result = db.replace(TABLE_NAME, null, cv);
        return result != -1;
    }

    // QUAN TRỌNG: Sử dụng AVG(salary)
    ArrayList getAllContacts() {
        SQLiteDatabase db = getReadableDatabase();
        ArrayList list = new ArrayList<>();
        
        // AVG() bỏ qua giá trị NULL
        String query = "SELECT AVG(salary) AS avg_salary FROM " + TABLE_NAME;
        Cursor res = db.rawQuery(query, null);
        
        if (res.moveToFirst()) {
            double avg = res.getDouble(res.getColumnIndexOrThrow("avg_salary"));
            list.add(String.format("Lương trung bình: %.2f", avg));
        }
        res.close();
        return list;
    }

    boolean update(String name, String salary) {
        SQLiteDatabase db = getWritableDatabase();
        ContentValues cv = new ContentValues();
        cv.put("name", name);
        try {
            cv.put("salary", Double.parseDouble(salary));
        } catch (NumberFormatException e) {
            cv.put("salary", salary);
        }
        int rows = db.update(TABLE_NAME, cv, null, null); // CẢNH BÁO: không WHERE
        return rows > 0;
    }

    boolean deleteAll() {
        SQLiteDatabase db = getWritableDatabase();
        int rows = db.delete(TABLE_NAME, null, null);
        return rows > 0;
    }
}

Chạy ứng dụng

Kết nối thiết bị, nhấn Run. Nhập vài bản ghi (Lưu), sau đó nhấn Tính AVG.

Kết quả

ListView hiển thị: "Lương trung bình: 7.500.000,00" (ví dụ)

Giải thích AVG() trong SQLite

  • AVG(cột): Tính trung bình cộng của các giá trị KHÔNG NULL trong cột
  • Kiểu trả về: Luôn là REAL (số thực), ngay cả khi cột là INTEGER
  • Bỏ qua NULL: Các hàng có salary = NULL không tính vào trung bình
  • Độ chính xác: SQLite dùng double precision (64-bit float)

Các hàm tổng hợp liên quan

HàmMô tả
SUM(cột)Tổng cộng
AVG(cột)Trung bình cộng
MIN(cột)Giá trị nhỏ nhất
MAX(cột)Giá trị lớn nhất
COUNT(cột)Số lượng (không NULL)
COUNT(*)Số hàng (kể NULL)
GROUP_CONCAT(cột)Nối chuỗi các giá trị

Ví dụ kết hợp:

SELECT 
    COUNT(*) as total,
    AVG(salary) as avg_salary,
    MIN(salary) as min_salary,
    MAX(salary) as max_salary,
    SUM(salary) as total_salary
FROM SalaryDetails;

Lưu ý: Code gốc cột salary khai báo "money" (không chuẩn SQLite). Đã sửa thành REAL. Cũng sửa getDouble() thay vì getString() để format đẹp. Cảnh báo UPDATE không WHERE.