কম্পিউটার টিউটোরিয়াল

অ্যান্ড্রয়েড SQLite-এ DISTINCT এবং COUNT ব্যবহার করা

অ্যান্ড্রয়েডে SQLite ডাটাবেস পরিচিতি

SQLite একটি ওপেন-সোর্স SQL ডাটাবেস যা ডিভাইসে টেক্সট ফাইল আকারে ডেটা সংরক্ষণ করে। অ্যান্ড্রয়েডে বিল্ট-ইন SQLite ইমপ্লিমেন্টেশন থাকে। এটি সকল রিলেশনাল ডাটাবেস ফিচার সাপোর্ট করে। এই ডাটাবেস অ্যাক্সেস করার জন্য JDBC বা ODBC-এর মতো কোনো কানেকশন স্থাপন করতে হয় না।

উদাহরণ: SQLite-এ DISTINCT এবং COUNT ব্যবহার করা

এই উদাহরণে দেখানো হয়েছে কিভাবে অ্যান্ড্রয়েড SQLite-এ DISTINCT এবং COUNT ফাংশন একসাথে ব্যবহার করে অনন্য (unique) রেকর্ডের সংখ্যা বের করা যায়।

স্টেপ ১: নতুন প্রজেক্ট তৈরি করুন

Android Studio-তে File → New Project এ যান এবং প্রয়োজনীয় বিবরণ পূরণ করে একটি নতুন প্রজেক্ট তৈরি করুন।

স্টেপ ২: লেআউট XML (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:hint="নাম লিখুন"
        android:layout_height="wrap_content" />

    <EditText
        android:id="@+id/salary"
        android:layout_width="match_parent"
        android:inputType="numberDecimal"
        android:hint="বেতন লিখুন"
        android:layout_height="wrap_content" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <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" />
        <Button
            android:id="@+id/delete"
            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">
    </ListView>
</LinearLayout>

উপরোক্ত কোডে নাম এবং বেতনের জন্য দুটি EditText ব্যবহার করা হয়েছে। Save বাটনে ক্লিক করলে ডেটা SQLite-এ সংরক্ষণ হবে। Refresh বাটনে ক্লিক করলে ListView-এ ডেটা প্রদর্শিত হবে।

স্টেপ ৩: 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;
    ArrayAdapter arrayAdapter;
    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 array_list = helper.getAllContacts();

        name = findViewById(R.id.name);
        salary = findViewById(R.id.salary);
        listView = findViewById(R.id.listView);

        arrayAdapter = new ArrayAdapter(MainActivity.this, android.R.layout.simple_list_item_1, array_list);
        listView.setAdapter(arrayAdapter);

        findViewById(R.id.delete).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (helper.delete()) {
                    Toast.makeText(MainActivity.this, "ডিলিট হয়েছে", Toast.LENGTH_LONG).show();
                } else {
                    Toast.makeText(MainActivity.this, "ডিলিট হয়নি", Toast.LENGTH_LONG).show();
                }
            }
        });

        findViewById(R.id.update).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!name.getText().toString().isEmpty() && !salary.getText().toString().isEmpty()) {
                    if (helper.update(name.getText().toString(), salary.getText().toString())) {
                        Toast.makeText(MainActivity.this, "আপডেট হয়েছে", Toast.LENGTH_LONG).show();
                    } else {
                        Toast.makeText(MainActivity.this, "আপডেট হয়নি", Toast.LENGTH_LONG).show();
                    }
                } else {
                    name.setError("নাম লিখুন");
                    salary.setError("বেতন লিখুন");
                }
            }
        });

        findViewById(R.id.refresh).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                array_list.clear();
                array_list.addAll(helper.getAllContacts());
                arrayAdapter.notifyDataSetChanged();
                listView.invalidateViews();
                listView.refreshDrawableState();
            }
        });

        findViewById(R.id.save).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!name.getText().toString().isEmpty() && !salary.getText().toString().isEmpty()) {
                    if (helper.insert(name.getText().toString(), salary.getText().toString())) {
                        Toast.makeText(MainActivity.this, "ইনসার্ট হয়েছে", Toast.LENGTH_LONG).show();
                    } else {
                        Toast.makeText(MainActivity.this, "ইনসার্ট হয়নি", Toast.LENGTH_LONG).show();
                    }
                } else {
                    name.setError("নাম লিখুন");
                    salary.setError("বেতন লিখুন");
                }
            }
        });
    }
}

স্টেপ ৪: 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.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;

class DatabaseHelper extends SQLiteOpenHelper {
    public static final String DATABASE_NAME = "salaryDatabase9";
    public static final String CONTACTS_TABLE_NAME = "SalaryDetails";

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

    @Override
    public void onCreate(SQLiteDatabase db) {
        try {
            db.execSQL("create table " + CONTACTS_TABLE_NAME + "(id INTEGER PRIMARY KEY, name text, salary float, 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 contentValues = new ContentValues();
        contentValues.put("name", name);
        contentValues.put("salary", salary);
        db.replace(CONTACTS_TABLE_NAME, null, contentValues);
        return true;
    }

    // COUNT(DISTINCT name) ব্যবহার করে অনন্য নামের সংখ্যা বের করা
    public ArrayList getAllContacts() {
        SQLiteDatabase db = this.getReadableDatabase();
        ArrayList<String> array_list = new ArrayList<String>();
        
        Cursor res = db.rawQuery("SELECT COUNT(DISTINCT name) as countRecords FROM " + CONTACTS_TABLE_NAME, null);
        
        res.moveToFirst();
        while (res.isAfterLast() == false) {
            if ((res != null) && (res.getCount() > 0))
                array_list.add(res.getString(res.getColumnIndex("countRecords")));
            res.moveToNext();
        }
        return array_list;
    }

    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;
    }
}

মূল পয়েন্ট: COUNT(DISTINCT column)

SELECT COUNT(DISTINCT column_name) FROM table_name

  • DISTINCT: ডুপ্লিকেট মানগুলো বাদ দিয়ে শুধু অনন্য মানগুলো বিবেচনা করে
  • COUNT(): সারি গণনা করে
  • যোগফল: ঐ কলামে কতগুলো আলাদা মান আছে সেটি বের করে

DISTINCT এবং COUNT-এর বিস্তারিত ব্যবহার

কোয়েরিফলাফলবর্ণনা
SELECT COUNT(*) FROM tableমোট রো সংখ্যাNULL সহ সব রো গণনা
SELECT COUNT(column) FROM tableNULL নয় মান সংখ্যাNULL বাদ দিয়ে গণনা
SELECT COUNT(DISTINCT column) FROM tableঅনন্য মান সংখ্যাডুপ্লিকেট বাদ দিয়ে গণনা
SELECT DISTINCT column FROM tableঅনন্য মান তালিকামানগুলো ফেরত দেয় (গণনা নয়)
SELECT DISTINCT col1, col2 FROM tableকম্বিনেশন ইউনিকদুই কলামের কম্বিনেশন ইউনিক

ব্যবহারিক উদাহরণ

-- ১. কতজন অনন্য কর্মচারী আছে?
SELECT COUNT(DISTINCT employee_id) FROM attendance;

-- ২. প্রতিটি বিভাগে কতজন অনন্য কর্মচারী?
SELECT department, COUNT(DISTINCT employee_id) 
FROM employees GROUP BY department;

-- ৩. অনন্য নামগুলো তালিকা করুন
SELECT DISTINCT name FROM SalaryDetails ORDER BY name;

-- ৪. ডুপ্লিকেট নামগুলো খুঁজুন
SELECT name, COUNT(*) as cnt 
FROM SalaryDetails 
GROUP BY name 
HAVING COUNT(*) > 1;

পারফরম্যান্স নোট

টিপ: বড় টেবিলে COUNT(DISTINCT column) ধীর হতে পারে, কারণ SQLite-কে সব রো স্ক্যান করে ডুপ্লিকেট ফিল্টার করতে হয়।

অপ্টিমাইজেশন: যদি সেটা অনন্য মান বাধ্যতামূলক হয় (UNIQUE কনস্ট্রেইন্ট), তাহলে COUNT(*) ব্যবহার করুন—তবে দ্রুত হবে।

অ্যাপ্লিকেশন চালানোর পদ্ধতি

  1. আপনার অ্যান্ড্রয়েড ডিভাইস কম্পিউটারের সাথে কানেক্ট করুন
  2. Android Studio-তে প্রজেক্টের এক্টিভিটি ফাইল খুলুন
  3. টুলবারের Run আইকনে ক্লিক করুন
  4. মোবাইল ডিভাইস সিলেক্ট করুন
  5. ডিভাইসে ডিফল্ট স্ক্রিন প্রদর্শিত হবে

অ্যান্ড্রয়েড SQLite-এ DISTINCT এবং COUNT ব্যবহার করা

উপরের ফলাফলে, অনন্য (non-repeated) রেকর্ডের সংখ্যা ২ দেখানো হচ্ছে।

সারসংক্ষেপ

এই টিউটোরিয়ালে আপনি শিখেছেন কিভাবে Android SQLite-এ COUNT(DISTINCT column) ব্যবহার করে কোনো কলামে কতগুলো অনন্য (unique) মান আছে সেটি বের করতে পারেন। এটি রিপোর্টিং, অ্যানালিটিক্স, ডেটা কোয়ালিটি চেক ইত্যাদিতে খুবই কাজে লাগে।

  1. অ্যান্ড্রয়েড SQLite-এ time() ফাংশন ব্যবহার করার পদ্ধতি

  2. অ্যান্ড্রয়েড SQLite-এ typeof() ফাংশন ব্যবহার করার পদ্ধতি

  3. অ্যান্ড্রয়েড SQLite-এ total_changes() ফাংশন ব্যবহার করার পদ্ধতি

  4. Android SQLite-এ COUNT() ফাংশন ব্যবহার করার পদ্ধতি