পাঠ ০৩ · ৩০-এর মধ্যে · মডিউল ১
Home / AI Courses / ডেটা সায়েন্স / SQL পরিচিতি

SQL পরিচিতি — SELECT, WHERE

SQL Basics — SELECT, FROM, WHERE, ORDER BY, LIMIT
৭ মিনিট পড়া মাঝারি · Intermediate Hands-on SQL

এই পাঠে যা শিখবেন

  • Relational database ও table-এর core ধারণা
  • SELECT, FROM, WHERE, ORDER BY, LIMIT — এই পাঁচটি keyword দিয়ে ৬০% query
  • Comparison ও logical operator — AND, OR, NOT, IN, BETWEEN, LIKE
  • Daraz/bKash-এর কাল্পনিক টেবিলে real-life query লেখা

১ · Relational database — কী ও কেন

Relational databaseRelational Databaseএকটি ডেটা সংরক্ষণের পদ্ধতি যেখানে ডেটা table-এ থাকে — প্রতিটি table-এ row (record) ও column (attribute)। Edgar F. Codd ১৯৭০-এ এই model আবিষ্কার করেন। MySQL, PostgreSQL, Oracle, SQL Server — সব এই model অনুসরণ করে। হলো ডেটা রাখার সবচেয়ে বহুল ব্যবহৃত পদ্ধতি — Excel sheet-এর মতো কিন্তু অনেক বড় ও নিয়মতান্ত্রিক। প্রতিটি table-এ:

  • Column (field): একটি attribute — যেমন customer_id, name, order_date।
  • Row (record): একটি instance — যেমন একজন গ্রাহকের সব তথ্য।
  • Primary key: একটি unique identifier — সাধারণত id।
  • Foreign key: অন্য table-এর primary key-এর reference — যা দিয়ে relationship তৈরি হয়।
Daraz-এর simplified schema

customers: customer_id, name, district, signup_date, age
products: product_id, name, category, price
orders: order_id, customer_id, product_id, quantity, total_amount, order_date, status

এই তিন table-এর মধ্যে relationship: orders.customer_id → customers.customer_id এবং orders.product_id → products.product_id। JOIN দিয়ে এদের মিলিয়ে query চালানো হয় (পরের পাঠে)।

২ · প্রথম query — SELECT & FROM

SQL-এর সবচেয়ে সরল pattern: "কোন column চাই, কোন table থেকে।"

SQL
-- সব গ্রাহকের নাম ও জেলা দেখান
SELECT name, district
FROM customers;

-- সব column চাইলে * use করুন (production-এ এড়িয়ে চলুন)
SELECT *
FROM customers;

    
Comma দিয়ে multiple column লিখুন। Semicolon (;) দিয়ে query শেষ হয়। Keyword (SELECT, FROM) সাধারণত uppercase লেখা হয় — readability-এর জন্য — যদিও SQL case-insensitive।

৩ · WHERE — filter condition

পুরো table দেখার বদলে — শুধু "যে row-গুলো condition পূরণ করে।" এটিই SQL-এর সবচেয়ে শক্তিশালী অংশ।

SQL
-- ঢাকা জেলার গ্রাহকরা
SELECT name, signup_date
FROM customers
WHERE district = 'Dhaka';

-- ১০,০০০ টাকার বেশি অর্ডার
SELECT order_id, total_amount, order_date
FROM orders
WHERE total_amount > 10000;

-- ২৫ থেকে ৩৫ বছর বয়সী গ্রাহক
SELECT name, age, district
FROM customers
WHERE age BETWEEN 25 AND 35;

-- নাম "র" দিয়ে শুরু
SELECT name
FROM customers
WHERE name LIKE 'র%';

    
Operator গুলো: =, != বা <>, <, >, <=, >=, BETWEEN, IN, LIKE, IS NULL। String value সবসময় 'single quote'-এ — double quote নয়।

৪ · Logical operators — AND, OR, NOT

একাধিক condition combine করতে:

SQL
-- ঢাকার ২৫+ বছর বয়সী গ্রাহক
SELECT name, age, district
FROM customers
WHERE district = 'Dhaka'
  AND age >= 25;

-- ঢাকা বা চট্টগ্রামের গ্রাহক
SELECT name, district
FROM customers
WHERE district = 'Dhaka' OR district = 'Chittagong';

-- IN দিয়ে আরো clean
SELECT name, district
FROM customers
WHERE district IN ('Dhaka', 'Chittagong', 'Sylhet');

-- ৩০-এর কম নয় এমন গ্রাহক
SELECT name, age
FROM customers
WHERE NOT age < 30;

    
AND/OR-এর parenthesis সাবধানে use করুন। গণিতের মতো precedence আছে — AND আগে evaluate হয় OR-এর চেয়ে। WHERE a OR b AND c মানে WHERE a OR (b AND c) — কখনোই (a OR b) AND c নয়। যখন সন্দেহ — bracket দিন।

৫ · ORDER BY — সাজানো

Default order undefined। নির্দিষ্ট order চাইলে:

SQL
-- বয়স অনুযায়ী ছোট থেকে বড় (ascending — default)
SELECT name, age
FROM customers
ORDER BY age;

-- বড় থেকে ছোট (descending)
SELECT name, age
FROM customers
ORDER BY age DESC;

-- multiple column — district তারপর age
SELECT name, district, age
FROM customers
ORDER BY district ASC, age DESC;

    

৬ · LIMIT — top-N

বিশাল table থেকে শুধু top কয়েকটি row। এটি performance-এর জন্যও critical — Daraz-এর ১০ কোটি row-এর table-এ SELECT * চালানো বিপজ্জনক।

SQL
-- top-১০ সবচেয়ে দামি অর্ডার
SELECT order_id, total_amount, order_date
FROM orders
ORDER BY total_amount DESC
LIMIT 10;

-- পাতা ২ (rows 11-20) — pagination
SELECT order_id, total_amount
FROM orders
ORDER BY order_id
LIMIT 10 OFFSET 10;

    
SQL flavor difference: PostgreSQL/MySQL-এ LIMIT n; SQL Server-এ SELECT TOP n; Oracle-এ ROWNUM <= n বা FETCH FIRST n ROWS ONLY। সিনট্যাক্স একটু আলাদা — কিন্তু concept একই।

৭ · Logical execution order — যে কারণে SQL "ঘুরে" চলে

আপনি লিখেন SELECT আগে — কিন্তু database প্রথমে FROM ও WHERE process করে, তারপর SELECT। এই pattern বুঝলে অনেক bug কমবে:

  1. FROM: কোন table থেকে?
  2. WHERE: কোন row রাখব?
  3. GROUP BY: grouping (পাঠ ৫-এ)।
  4. HAVING: group-level filter।
  5. SELECT: কোন column বের করব?
  6. ORDER BY: result সাজাও।
  7. LIMIT: top-N।
SQL — লিখি যেভাবে, চলে যেভাবে Writing order vs Logical execution order 📝 আমরা লিখি SELECT name, age FROM customers WHERE district='Dhaka' ORDER BY age DESC LIMIT 10; ⚙️ Database চালায় ১ · FROM customers ২ · WHERE filter ৩ · SELECT columns ৪ · ORDER BY ৫ · LIMIT 10 কেন SELECT-এ alias WHERE-এ use করা যায় না — কারণ WHERE আগে চলে।
SQL-এর "মন্ত্র" — লেখার order ≠ execution order। এই গণ্ডগোল ৭৫% SQL bug-এর উৎস।

৮ · NULL — অনুপস্থিত value

ডেটায় missing value নিয়ে অনেক confusion। SQL-এ NULL মানে "অজানা" — শূন্য বা empty string নয়।

  • WHERE phone = NULL ভুল — কারণ NULL সাথে কোনো comparison সবসময় NULL (অর্থাৎ false-এর মতো)।
  • সঠিক: WHERE phone IS NULL বা WHERE phone IS NOT NULL।
  • NULL + ৫ = NULL। NULL OR true = true; NULL AND true = NULL।
বাস্তব ডেটায় NULL খুব common — বিশেষ করে optional field-এ। সবসময় NULL handling explicit রাখুন। Production-এ ভুল NULL handle থেকে অনেক bug আসে।

৯ · Best practices — পেশাদার SQL লেখা

  • Format: Keyword uppercase, table/column lowercase, indentation consistent।
  • Comments: -- single line, /* multi line */। Complex query-তে business intent লিখুন।
  • Avoid SELECT *: production query-তে specific column লিখুন — schema change-এ break হবে না।
  • LIMIT during exploration: বড় table-এ "SELECT *" ছাড়া LIMIT 100 দিন — দ্রুত ও সাবধান।
  • Use aliases: long table name-এ alias — FROM orders o WHERE o.amount > 100।
  • EXPLAIN: slow query-তে EXPLAIN দিয়ে execution plan দেখুন।

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।

প্র ০১ SQL ১৯৭০-এ আবিষ্কৃত — তখন থেকে NoSQL, GraphQL, ও বহু alternative এসেছে। তবু SQL আজও dominant। এর কারণ কী — কেন এই ৫০ বছরের পুরোনো language replace হলো না?

SQL-এর dominance computer science-এর সবচেয়ে রহস্যময় survival story-গুলোর একটি।

SQL টিকে আছে যেসব কারণে:

  • Declarative paradigm: "কী চাই" বলেন, "কীভাবে আনব" database optimizer ঠিক করে। Imperative language (Java, Python loop) "কীভাবে" লিখতে বাধ্য করে — ১০x কোড।
  • Relational model-এর গাণিতিক ভিত্তি: Codd-এর relational algebra — ৪ দশকের academic foundation। Join, projection, selection — সবই formally defined।
  • Standardization: ANSI/ISO SQL standard — PostgreSQL, MySQL, Oracle, SQL Server — সব প্রায় একই syntax।
  • Optimizer maturity: ৫০ বছরের research — index, query plan, parallel execution — যা NoSQL-এ এখনো পরিপক্ব নয়।
  • ACID guarantees: bank/finance-এ data integrity non-negotiable।
  • Tooling ecosystem: BI tools (Tableau, Power BI), ORM (Hibernate, SQLAlchemy), monitoring — সব SQL-অনুকূল।

NoSQL কেন wholesale replace করতে পারল না:

  • ২০১০-এর "NoSQL revolution" "schema-less", "scale-out" দিয়ে বিজয় ঘোষণা করেছিল। বাস্তবে — schema-less মানে schema আপনার application-এ চলে যায়।
  • Distributed transactions NoSQL-এ এখনো পেইনফুল।
  • Analytics queries NoSQL-এ awkward — তাই MongoDB-এও SQL-like aggregation framework এসেছে।

আজকের convergence:

  • NewSQL: CockroachDB, Spanner, TiDB — distributed + ACID + SQL।
  • Lakehouse SQL: Databricks, Snowflake — petabyte-scale-এ SQL।
  • NoSQL+SQL: MongoDB Aggregation, Cassandra CQL — SQL-like।
  • Embedded SQL: SQLite — মোবাইল ফোন থেকে browser পর্যন্ত।

Bangladesh perspective:

  • Daraz, Pathao, bKash — সবাই PostgreSQL/MySQL stack ব্যবহার করে।
  • Bank legacy core — Oracle/DB2-এ SQL।
  • Government data warehouse — SQL-based।

মূল উপলব্ধি: SQL-এ "boring stability" আছে যা flashy alternative-গুলোতে নেই। ৫০ বছর পরও SQL শেখা = high ROI। এটিই data analyst-এর সবচেয়ে durable skill।

প্র ০২ "SELECT *" production-এ এড়াতে বলা হয়। কিন্তু exploration-এ আমরা এটি use করি। এই দ্বিধা কেন — কখন * ভাল, কখন বিপজ্জনক?

একটি practical SQL hygiene topic যা senior দের অভ্যাসে দেখা যায়।

"SELECT *"-এর সমস্যাগুলো:

  1. Performance: বড় table-এ unnecessary column transfer — network bandwidth, memory, parsing খরচ।
  2. Schema fragility: table-এ নতুন column add হলে আপনার downstream code break — বিশেষত যদি column order assume করেন।
  3. Security: Sensitive column (NID, ফোন, password hash) accidentally expose।
  4. Index inefficiency: Covering index miss করতে পারে; database column subset retrieve-এ optimized হয়।
  5. Documentation: Reader-এর কাছে — কোন column actually use করা হচ্ছে অস্পষ্ট।
  6. Cache invalidation: Application-level cache "যা দরকার তা" cache করতে পারে না — সব আনতে বাধ্য।

কখন "*" ঠিক:

  • Initial exploration: "এই table-এ কী আছে?" first 10 rows দেখা।
  • Schema discovery: SELECT * FROM table LIMIT 0 — শুধু column structure।
  • Backup/dump: পুরো table copy দরকার।
  • Subquery-তে EXISTS check: EXISTS (SELECT * FROM ...) — actual column return হয় না।
  • "SELECT count(*)": এটি বিশেষ syntax, optimized।

Best practice progression:

  • Exploration phase — SELECT * + LIMIT 100।
  • Notebook analysis — column list note, narrow করা।
  • Production query — explicit column list সবসময়।
  • Review checklist — code review-এ SELECT * red flag।

SQL anti-pattern collections:

  • SELECT * production-এ — fragile।
  • WHERE column = NULL — অর্থহীন।
  • Implicit JOIN (FROM a, b) — Cartesian product risk।
  • ORDER BY ছাড়া LIMIT — non-deterministic।
  • HAVING + WHERE বিভ্রান্তি (পাঠ ৫)।

মূল উপলব্ধি: Tool-কে context-এ judge করুন। "*" বদনাম নয় — production-এ অপব্যবহার বদনাম। Senior dev-রা explicit column লেখেন, কিন্তু exploration-এ pragmatic।

প্র ০৩ আপনি Daraz-এ join করেছেন। প্রথম দিন একজন senior বললেন — "production database-এ যেকোনো query চালানোর আগে দু'বার ভাবো।" কেন এই warning — কোন কোন situation-এ একটি innocent SELECT অনিরাপদ হতে পারে?

"It's just a SELECT" — junior-দের সবচেয়ে costly assumption।

SELECT-এর danger zones:

  1. Lock contention:
    • কিছু DB-তে SELECT row-level shared lock নেয়।
    • একটি massive query চলাকালীন write transaction wait করে — production traffic stall।
    • "WITH (NOLOCK)" বা "READ UNCOMMITTED" use নিরাপদ exploration-এ — কিন্তু dirty read risk।
  2. Resource exhaustion:
    • SELECT * FROM orders ১০ কোটি row — RAM exhausted, query killer triggered।
    • Disk I/O surge — অন্য query slow।
    • Network saturation — cluster-এ replication lag।
  3. Query plan trap:
    • Index miss — full table scan। ১০ মিনিট plus।
    • Bad join (Cartesian product) — explosion of rows।
    • WHERE LOWER(name) = 'rahim' — function on column → index unused।
  4. Data sensitivity:
    • Customer PII (NID, ফোন, বাসা) দেখা — audit log-এ যায়, compliance issue।
    • Bangladesh Data Protection Act + GDPR-এ purpose-bound access।
    • Screen recording / clipboard — accidentally exposed।
  5. Replica lag:
    • "যা production-এ দেখছি তা real-time না হতে পারে" — replica ৫-৩০ সেকেন্ড পেছনে।
    • Critical decision-এ stale data ভয়ংকর।

Safe-query disciplines:

  • Read-replica use: production write DB-তে নয়, read replica/data warehouse-এ।
  • EXPLAIN আগে: বড় query-এর plan দেখুন; full table scan হলে rewrite।
  • LIMIT discipline: exploration-এ LIMIT 100 — even when you "need all"।
  • WHERE-এ filter আগে: partition column বা indexed column-এ filter।
  • Time-window: off-peak (রাত)-এ heavy query।
  • Sandbox first: staging/dev DB-তে test।
  • Sample-first principle: TABLESAMPLE বা WHERE rand() < 0.01 দিয়ে ১% sample।

Disaster stories (anonymized):

  • একটি bank-এ junior SELECT * FROM transaction_history — ৩ ঘণ্টা production stall, customer ATM block।
  • একটি e-commerce-এ WHERE date_trunc('day', ts) = ... — full scan, ATC service down।
  • Marketing analyst PII export দিয়ে Excel-এ পাঠালেন — compliance violation, fine।

মূল উপলব্ধি: Production DB একটি live organism। SELECT "harmless" নয় — যথাযথ discipline না থাকলে blast radius বিশাল। Senior-দের কাছে "paranoid" শেখা আজীবন valuable।

প্র ০৪ SQL শিখতে গিয়ে অনেকে বলেন — "Python-এ pandas আছে, SQL শেখার দরকার কী?" এই argument কতটা ঠিক — কোন কাজে SQL irreplaceable?

একটি প্রতিনিয়ত আসা প্রশ্ন। উত্তর nuanced।

Pandas-এর strength:

  • Python ecosystem-এর সাথে seamless — visualization, ML directly।
  • Complex data manipulation expressive (groupby + apply + lambda)।
  • In-memory speed — small/medium dataset-এ দ্রুত।
  • Notebook-এ interactive exploration।

SQL-এর irreplaceable strengths:

  1. Scale:
    • Pandas RAM-bound — ১০ GB-এর বেশি কঠিন।
    • SQL ১০০ TB-এ চলে — Snowflake, BigQuery, Redshift।
    • Enterprise data ১০-১০০x বড় pandas-এর সীমা থেকে।
  2. Source of truth:
    • Production data DB-তে। Pandas চালাতে আগে SQL দিয়ে টানতে হবে।
    • "Pandas vs SQL" নয় — "SQL → Pandas → SQL" pipeline।
  3. Engineering integration:
    • Backend developer SQL জানেন, pandas নয়।
    • BI tool, ETL, dbt — সব SQL-driven।
    • Cross-team collaboration-এ SQL universal।
  4. Job market:
    • "SQL required" — almost every data job posting।
    • Bangladesh-এ ৯৫% data analyst-এর interview প্রথম প্রশ্ন SQL।
    • SQL skill-এ salary premium বড়।
  5. Optimization & index:
    • SQL engine ৫০ বছরের optimization research। Pandas naive।
    • Indexed query milliseconds; pandas equivalent seconds-minutes।
  6. Concurrency & ACID:
    • Multi-user, transactional integrity — pandas-এ অপ্রাপ্য।

Best practice — দুটোই use করুন:

  • SQL: filter, aggregate, join — DB-তে যা সবচেয়ে efficient।
  • Pandas: SQL output-এ Python-specific transformations, ML feature engineering।
  • Pull less data: SQL-এ aggregate করে বড় table → ছোট result, তারপর pandas।
  • Avoid round-trip: Loop-এ pandas → SQL query — disastrous।

Modern bridge tools:

  • DuckDB: embedded SQL — pandas-এর সাথে seamless।
  • Polars: Rust-based, SQL-like + pandas-like, faster।
  • Ibis: Python API, SQL backend।
  • SQLAlchemy: ORM, pandas read_sql।

মূল উপলব্ধি: "SQL or pandas" false dichotomy। দু'টি complementary। SQL data engineer-এর mother tongue; pandas analyst-এর scratchpad। দু'টিতেই fluent হওয়া modern data scientist-এর hallmark।

অনুশীলন

  1. Daraz-এর customer table থেকে: "ঢাকা" বা "চট্টগ্রাম"-এর ৩০ বছরের কম বয়সী গ্রাহক, বয়স অনুযায়ী descending — top ১০।
    SELECT name, age, district
    FROM customers
    WHERE district IN ('Dhaka', 'Chittagong')
      AND age < 30
    ORDER BY age DESC
    LIMIT 10;

    Note: IN use করলে পরিষ্কার, পঞ্চাশ জেলার জন্য আরো expandable।

  2. Order table থেকে: গত ৭ দিনে completed status-এর order — top-৫ amount-অনুযায়ী।
    SELECT order_id, total_amount, order_date
    FROM orders
    WHERE status = 'completed'
      AND order_date >= CURRENT_DATE - INTERVAL '7 days'
    ORDER BY total_amount DESC
    LIMIT 5;

    Tip: Date function DB-ভেদে আলাদা — PostgreSQL-এ CURRENT_DATE - INTERVAL '7 days'; MySQL-এ DATE_SUB(CURDATE(), INTERVAL 7 DAY)।

  3. NULL handling: customers table-এ এমন গ্রাহক বের করুন যাদের phone column NULL — অর্থাৎ ফোন নম্বর নেই।
    SELECT customer_id, name, signup_date
    FROM customers
    WHERE phone IS NULL;

    Common mistake: WHERE phone = NULL — কখনো row return করবে না, কারণ NULL = NULL → NULL (false-এর মতো আচরণ)। সর্বদা IS NULL বা IS NOT NULL।

আরও পড়ুন

Practice করতে চান? SQLite Fiddle বা DB Fiddle — browser-এই SQL চালান।
পূর্ববর্তী পাঠ
পাঠ ০২ · CRISP-DM