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

Cách hiển thị bản ghi theo thứ tự giảm dần (DESC) trong SQLite Android

ORDER BY DESC - Sắp xếp giảm dần trong SQLite

Từ khóa DESC (descending) sắp xếp kết quả từ lớn đến nhỏ. Mặc định là ASC (ascending - tăng dần).

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

Android Studio → File → New Project.

Bước 2: Giao diện (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"
    android:padding="16dp">

    <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" android:layout_marginTop="8dp">
        <Button android:id="@+id/save" android:text="Lưu" android:layout_width="wrap_content" android:layout_height="wrap_content" />
        <Button android:id="@+id/refresh" android:text="Làm mới" android:layout_width="wrap_content" android:layout_height="wrap_content" />
        <Button android:id="@+id/update" android:text="Cập nhật" 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" android:layout_marginTop="16dp" />
</LinearLayout>

Bước 3: MainActivity.java

package com.example.sqlitedesc;

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 btnSave, btnRefresh, btnUpdate;
    EditText edtName, edtSalary;
    ListView listView;
    DatabaseHelper dbHelper;
    ArrayList dataList;
    ArrayAdapter adapter;

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

        dbHelper = new DatabaseHelper(this);
        dataList = new ArrayList<>(dbHelper.getAllContacts());
        
        edtName = findViewById(R.id.name);
        edtSalary = findViewById(R.id.salary);
        listView = findViewById(R.id.listView);
        btnSave = findViewById(R.id.save);
        btnRefresh = findViewById(R.id.refresh);
        btnUpdate = findViewById(R.id.update);

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

        btnRefresh.setOnClickListener(v -> refreshList());
        
        btnSave.setOnClickListener(v -> {
            String name = edtName.getText().toString().trim();
            String salary = edtSalary.getText().toString().trim();
            if (name.isEmpty() || salary.isEmpty()) {
                showError(name, salary);
                return;
            }
            if (dbHelper.insert(name, salary)) {
                Toast.makeText(this, "Đã thêm", Toast.LENGTH_SHORT).show();
                refreshList();
            } else {
                Toast.makeText(this, "Thêm thất bại", Toast.LENGTH_SHORT).show();
            }
        });

        btnUpdate.setOnClickListener(v -> {
            String name = edtName.getText().toString().trim();
            String salary = edtSalary.getText().toString().trim();
            if (name.isEmpty() || salary.isEmpty()) {
                showError(name, salary);
                return;
            }
            if (dbHelper.update(name, salary)) {
                Toast.makeText(this, "Đã cập nhật", Toast.LENGTH_SHORT).show();
                refreshList();
            } else {
                Toast.makeText(this, "Cập nhật thất bại", Toast.LENGTH_SHORT).show();
            }
        });
    }

    private void refreshList() {
        dataList.clear();
        dataList.addAll(dbHelper.getAllContacts());
        adapter.notifyDataSetChanged();
    }

    private void showError(String name, String salary) {
        if (name.isEmpty()) edtName.setError("Nhập tên");
        if (salary.isEmpty()) edtSalary.setError("Nhập lương");
    }
}

Bước 4: DatabaseHelper.java - ORDER BY name DESC

package com.example.sqlitedesc;

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;

public class DatabaseHelper extends SQLiteOpenHelper {
    private static final String DATABASE_NAME = "salaryDatabase";
    private static final String TABLE_NAME = "SalaryDetails";
    private static final int DB_VERSION = 1;

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

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE " + TABLE_NAME + 
            "(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, salary TEXT, datetime DEFAULT CURRENT_TIMESTAMP)");
    }

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

    public boolean insert(String name, String salary) {
        SQLiteDatabase db = getWritableDatabase();
        ContentValues cv = new ContentValues();
        cv.put("name", name);
        cv.put("salary", salary);
        return db.insert(TABLE_NAME, null, cv) != -1;
    }

    // SẮP XẾP GIẢM DẦN THEO TÊN (Z → A)
    public ArrayList getAllContacts() {
        ArrayList list = new ArrayList<>();
        SQLiteDatabase db = getReadableDatabase();
        
        Cursor cursor = db.rawQuery(
            "SELECT name FROM " + TABLE_NAME + " ORDER BY name DESC", null);

        if (cursor.moveToFirst()) {
            do {
                list.add(cursor.getString(cursor.getColumnIndex("name")));
            } while (cursor.moveToNext());
        }
        cursor.close();
        return list;
    }

    public boolean update(String name, String salary) {
        SQLiteDatabase db = getWritableDatabase();
        ContentValues cv = new ContentValues();
        cv.put("name", name);
        cv.put("salary", salary);
        return db.update(TABLE_NAME, cv, "name = ?", new String[]{name}) > 0;
    }

    public boolean deleteAll() {
        return getWritableDatabase().delete(TABLE_NAME, null, null) > 0;
    }
}

Các dạng ORDER BY phổ biến

-- 1. Một cột
ORDER BY name DESC           -- Z → A
ORDER BY salary DESC         -- Lớn → Nhỏ
ORDER BY datetime DESC       -- Mới → Cũ

-- 2. Nhiều cột (ưu tiên từ trái sang phải)
ORDER BY name DESC, salary ASC    -- Tên Z→A, cùng tên thì lương nhỏ→lớn
ORDER BY department ASC, salary DESC  -- Phòng ban A→Z, trong phòng lương cao→thấp

-- 3. Kết hợp với WHERE
SELECT * FROM employees WHERE active = 1 ORDER BY hire_date DESC;

-- 4. Kết hợp với LIMIT (phân trang)
ORDER BY created_at DESC LIMIT 20 OFFSET 0;  -- Trang 1, 20 bản ghi mới nhất

-- 5. Sắp xếp theo biểu thức
ORDER BY LENGTH(name) DESC      -- Tên dài nhất lên đầu
ORDER BY (salary * bonus) DESC  -- Thu nhập tổng giảm dần

ASC vs DESC - Tóm tắt

Từ khóaThứ tựVí dụ kết quả
ASC (mặc định)Tăng dầnA, B, C / 1, 2, 10 / Cũ → Mới
DESCGiảm dầnZ, Y, X / 100, 50, 1 / Mới → Cũ

Lưu ý hiệu năng

  • Tạo INDEX trên cột ORDER BY thường dùng: CREATE INDEX idx_name ON SalaryDetails(name);
  • INDEX giúp ORDER BY nhanh hơn (tránh filesort).
  • Kết hợp WHERE + ORDER BY: Index composite (WHERE_col, ORDER_col).
  • LIMIT nhỏ + ORDER BY có index = rất nhanh.

Ví dụ thực tế: Danh sách tin tức mới nhất

// Query: 10 tin tức mới nhất, đã xuất bản
String sql = "SELECT * FROM news " +
             "WHERE published = 1 " +
             "ORDER BY publish_date DESC " +
             "LIMIT 10";