SQL Queries: Commands, Joins, Subqueries and Classic Exam Queries · এসকিউএল কোয়েরি: কমান্ড, জয়েন, সাবকোয়েরি ও পরীক্ষার পরিচিত কোয়েরি
SQL (Structured Query Language) is the standard language of relational databases; its commands fall into DDL (CREATE, ALTER, DROP, TRUNCATE), DML (INSERT, UPDATE, DELETE, and SELECT, which some books list separately as DQL), DCL (GRANT, REVOKE) and TCL (COMMIT, ROLLBACK, SAVEPOINT). A query is written SELECT … FROM … WHERE … GROUP BY … HAVING … ORDER BY but is logically processed FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY, which is why WHERE cannot use an aggregate directly and HAVING can. Joins combine tables (INNER keeps only matching rows; LEFT, RIGHT and FULL OUTER also keep unmatched rows with NULLs), and subqueries with IN, ANY, ALL and EXISTS let one query use another's result.
এসকিউএল (Structured Query Language) রিলেশনাল ডেটাবেজের প্রমিত ভাষা; এর কমান্ডগুলো ডিডিএল (CREATE, ALTER, DROP, TRUNCATE), ডিএমএল (INSERT, UPDATE, DELETE; আর SELECT, যাকে কিছু বই আলাদা করে ডিকিউএল বলে), ডিসিএল (GRANT, REVOKE) ও টিসিএল (COMMIT, ROLLBACK, SAVEPOINT) ভাগে পড়ে। কোয়েরি লেখা হয় SELECT … FROM … WHERE … GROUP BY … HAVING … ORDER BY ক্রমে, কিন্তু যৌক্তিকভাবে চলে FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY ক্রমে; এ কারণেই WHERE-এ সরাসরি অ্যাগ্রিগেট ফাংশন ব্যবহার করা যায় না, HAVING-এ যায়। জয়েন একাধিক টেবিল যুক্ত করে (INNER শুধু মিলে যাওয়া সারি রাখে; LEFT, RIGHT ও FULL OUTER না-মেলা সারিও NULL সহ রাখে), আর IN, ANY, ALL ও EXISTS দিয়ে সাবকোয়েরি একটি কোয়েরির ফল আরেকটিতে ব্যবহার করতে দেয়।
- Asked in past exams
- 94
- Papers
- 72
1. What SQL is and its command groups
SQL (Structured Query Language) is the standard language for relational databases (MySQL, Oracle, PostgreSQL, SQL Server, SQLite). It was developed at IBM in the 1970s (first called SEQUEL), became an ANSI standard in 1986 and an ISO standard (ISO/IEC 9075) in 1987. It is declarative: you say what rows you want, and the DBMS decides how to fetch them. Keywords are not case-sensitive; every statement ends with ;.
| Group | Full form | Job | Commands |
|---|---|---|---|
| DDL | Data Definition Language | Define or change structure | CREATE, ALTER, DROP, TRUNCATE, RENAME |
| DML | Data Manipulation Language | Change the data | INSERT, UPDATE, DELETE (MERGE) |
| DQL | Data Query Language | Read the data | SELECT |
| DCL | Data Control Language | Permissions | GRANT, REVOKE |
| TCL | Transaction Control Language | Transactions | COMMIT, ROLLBACK, SAVEPOINT |
Many books and BD exam keys put SELECT under DML and name only three groups (DDL, DML, DCL); if DQL is not among the options, SELECT is DML. TRUNCATE removes rows but is DDL.
GRANT SELECT, INSERT ON Employee TO clerk; -- DCL: give rights
REVOKE INSERT ON Employee FROM clerk; -- DCL: take a right back
2. The sample tables used on this page
CREATE TABLE Department (
dept_id INTEGER PRIMARY KEY,
dept_name VARCHAR(20) NOT NULL UNIQUE
);
CREATE TABLE Employee (
emp_id INTEGER PRIMARY KEY,
name VARCHAR(30) NOT NULL,
dept_id INTEGER REFERENCES Department(dept_id),
salary INTEGER CHECK (salary > 0),
manager_id INTEGER REFERENCES Employee(emp_id)
);
Department
| dept_id | dept_name |
|---|---|
| 10 | CSE |
| 20 | EEE |
| 30 | HR |
| 40 | Audit |
Employee
| emp_id | name | dept_id | salary | manager_id |
|---|---|---|---|---|
| 1 | Rafiq | 10 | 50000 | NULL |
| 2 | Karim | 10 | 40000 | 1 |
| 3 | Salma | 20 | 60000 | 1 |
| 4 | Nadia | 20 | 40000 | 3 |
| 5 | Tanvir | NULL | 30000 | 3 |
| 6 | Mitu | 10 | NULL | 1 |
Tanvir has no department, Mitu's salary is unknown, and HR and Audit have no staff: these rows are there on purpose, because exam traps live in NULLs and unmatched rows. The constraints work: inserting an employee with dept_id 99 fails with "FOREIGN KEY constraint failed", and a salary of −5 fails the CHECK.
More DDL that exams ask about:
- CHAR(n) vs VARCHAR(n): CHAR is fixed length (a shorter value is padded with spaces to n); VARCHAR is variable length (it stores only the characters given, up to n).
- DEFAULT gives a column its value when an INSERT leaves it out:
status VARCHAR(10) DEFAULT 'active'. - ON DELETE CASCADE on a foreign key deletes the child rows when their parent row is deleted; without it, deleting a parent that still has children fails (checked in SQLite: "FOREIGN KEY constraint failed").
- ALTER TABLE changes a table:
ALTER TABLE Employee ADD COLUMN email VARCHAR(50);andALTER TABLE Employee DROP COLUMN email;(Oracle and SQL Server leave out the word COLUMN after ADD). To change a column's type, MySQL and Oracle writeMODIFY salary DECIMAL(10,2), while SQL Server and PostgreSQL write ALTER COLUMN; SQLite has neither.
3. SELECT and the logical order of its clauses
SELECT dept_id, COUNT(*) AS staff, AVG(salary) AS avg_sal -- 5
FROM Employee -- 1
WHERE salary IS NOT NULL -- 2
GROUP BY dept_id -- 3
HAVING COUNT(*) >= 2 -- 4
ORDER BY avg_sal DESC; -- 6
Worked example 1: run the query above step by step.
- FROM takes all 6 Employee rows.
- WHERE salary IS NOT NULL drops Mitu: 5 rows left.
- GROUP BY dept_id makes three groups: NULL {Tanvir}, 10 {Rafiq, Karim}, 20 {Salma, Nadia}. (All NULLs fall into one group.)
- HAVING COUNT(*) >= 2 drops the NULL group (1 row).
- SELECT computes the averages: dept 10 → (50000 + 40000) / 2 = 45000; dept 20 → (60000 + 40000) / 2 = 50000.
- ORDER BY avg_sal DESC puts 20 first.
| dept_id | staff | avg_sal |
|---|---|---|
| 20 | 2 | 50000.0 |
| 10 | 2 | 45000.0 |
The order explains three rules: FROM is processed first; WHERE cannot use an aggregate (groups do not exist yet), so aggregates go in SELECT or HAVING; and a SELECT alias cannot be used in WHERE (standard SQL, MySQL, Oracle), though ORDER BY can use it. Other operators in WHERE: BETWEEN 40000 AND 50000 (inclusive: Rafiq, Karim, Nadia), IN (…), LIKE 'r%' (% = zero or more characters, _ = exactly one character), IS NULL. To remove duplicate rows from a result use DISTINCT; to sort use ORDER BY (ASC by default).
4. Aggregate functions and NULL
SELECT COUNT(*), COUNT(salary), SUM(salary), AVG(salary), MIN(salary), MAX(salary)
FROM Employee;
| COUNT(*) | COUNT(salary) | SUM | AVG | MIN | MAX |
|---|---|---|---|---|---|
| 6 | 5 | 220000 | 44000.0 | 30000 | 60000 |
- COUNT(*) counts rows (6); COUNT(salary) counts non-NULL values (5).
- Every aggregate except COUNT(*) ignores NULL, so AVG = 220000 / 5 = 44000, not 220000 / 6 = 36666.67.
- COUNT(DISTINCT salary) = 4 (60000, 50000, 40000, 30000).
NULL rules. NULL means unknown, so any comparison with it is unknown, never true:
| Expression | Result |
|---|---|
| NULL = NULL | NULL (unknown), not true |
| NULL IS NULL | true (1) |
| 5 + NULL | NULL |
| COALESCE(NULL, 0) | 0 |
WHERE salary = NULL |
0 rows |
WHERE salary IS NULL |
Mitu |
5. Joins: a worked example
Worked example 2: Employee joined with Department on dept_id.
| Join | Rows | What happens to Tanvir (no dept) and HR, Audit (no staff) |
|---|---|---|
| INNER JOIN | 5 | All three dropped |
| LEFT JOIN (Employee left) | 6 | Tanvir kept with dept_name NULL |
| RIGHT JOIN | 7 | HR and Audit kept with name NULL; Tanvir dropped |
| FULL OUTER JOIN | 8 | All kept: 5 matches + Tanvir + HR + Audit |
| CROSS JOIN | 24 | No condition: 6 × 4 pairs |
SELECT e.name, d.dept_name
FROM Employee e
LEFT JOIN Department d ON e.dept_id = d.dept_id
ORDER BY e.emp_id;
| name | dept_name |
|---|---|
| Rafiq | CSE |
| Karim | CSE |
| Salma | EEE |
| Nadia | EEE |
| Tanvir | NULL |
| Mitu | CSE |
How to count without running: INNER = matching pairs (5); LEFT = INNER + unmatched left rows (5 + 1); RIGHT = INNER + unmatched right rows (5 + 2); FULL = INNER + both (5 + 1 + 2). "Which join keeps rows that have no match?" → an outer join.
Three more names exams use: an equi-join is a join whose condition uses only = (the joins above); a NATURAL JOIN is an equi-join on all same-named columns that shows each such column once (Employee NATURAL JOIN Department joins on dept_id: 5 rows); a theta join uses any comparison (<, >, ≠), so ON e.dept_id < d.dept_id gives 13 rows. CROSS JOIN is the Cartesian product.
A self join joins a table to itself with two aliases:
SELECT e.name AS employee, m.name AS manager
FROM Employee e JOIN Employee m ON e.manager_id = m.emp_id;
This returns 5 rows (Karim–Rafiq, Salma–Rafiq, Nadia–Salma, Tanvir–Salma, Mitu–Rafiq); Rafiq has no manager, so the inner join drops him. Adding WHERE e.salary > m.salary finds employees who earn more than their manager: Salma (60000 > 50000).
6. Subqueries: IN, ANY, ALL, EXISTS and correlated
| Form | True when | Example on our data | Result |
|---|---|---|---|
| x IN (subquery) | x equals some value returned | dept_id IN (ids of CSE, HR) | Rafiq, Karim, Mitu |
| x > ANY (subquery) | x is greater than at least one value (same as > MIN when the subquery returns at least one row and no NULL) | salary > ANY (dept 20 salaries: 60000, 40000) | Rafiq, Salma |
| x >= ALL (subquery) | x is at least every value (same as >= MAX when the subquery returns at least one row and no NULL; on an empty subquery ALL is true) | salary >= ALL (dept 20 salaries) | Salma |
| EXISTS (subquery) | the subquery returns at least one row | departments with an employee | CSE, EEE |
| NOT EXISTS (subquery) | the subquery returns no row | departments with no employee | HR, Audit |
-- EXISTS: departments that have at least one employee
SELECT d.dept_name FROM Department d
WHERE EXISTS (SELECT 1 FROM Employee e WHERE e.dept_id = d.dept_id);
-- Correlated subquery: employees paid above their own department's average
SELECT name, salary FROM Employee e
WHERE salary > (SELECT AVG(salary) FROM Employee WHERE dept_id = e.dept_id);
The second query is correlated: the inner query uses e.dept_id from the outer row, so it runs once per row. Dept 10's average is 45000 (Mitu's NULL ignored) and dept 20's is 50000, so the result is Rafiq 50000 and Salma 60000. Tanvir is excluded because dept_id = NULL is never true.
SQLite does not support ANY and ALL (a syntax error), so on SQLite write the MIN/MAX form; MySQL, Oracle, PostgreSQL and SQL Server support both.
7. Set operators: UNION vs UNION ALL
Both queries must return the same number of columns with compatible types.
| Operator | Keeps | dept_id from Employee (6 rows) with dept_id from Department (4 rows) |
|---|---|---|
| UNION | Distinct rows only | 5 rows: NULL, 10, 20, 30, 40 |
| UNION ALL | Every row, duplicates too (faster: no duplicate check) | 10 rows |
| INTERSECT | Rows in both | 10, 20 |
| EXCEPT (Oracle: MINUS) | Rows in the first, not the second | NULL (Employee EXCEPT Department); Department EXCEPT Employee gives 30, 40 |
SQLite, PostgreSQL and SQL Server use EXCEPT; Oracle uses MINUS (SQLite rejects MINUS). MySQL has INTERSECT and EXCEPT only from 8.0.31.
8. DELETE vs TRUNCATE vs DROP
| Point | DELETE | TRUNCATE | DROP |
|---|---|---|---|
| Group | DML | DDL | DDL |
| Removes | Chosen rows (WHERE) or all rows | All rows | The whole table: rows, structure, indexes |
| WHERE allowed | Yes | No | No |
| Table exists afterwards | Yes | Yes, empty | No |
| Rollback | Yes, inside a transaction | Oracle and MySQL: no (implicit commit); PostgreSQL and SQL Server: yes inside a transaction | Oracle and MySQL: no (implicit commit); PostgreSQL and SQL Server: yes inside a transaction |
| Row triggers fire | Yes | No | No |
| Speed | Slower, logs each row | Fast, deallocates pages | Fast |
| Auto-increment counter | Kept | Reset (MySQL, SQL Server) | Gone with the table |
Checked in SQLite: inside BEGIN … ROLLBACK, DELETE FROM Employee WHERE salary < 45000 removed 3 rows (Karim, Nadia, Tanvir), and ROLLBACK brought the count back to 6. SQLite has no TRUNCATE (syntax error); a DELETE FROM t without WHERE does the same job. After DROP TABLE T, SELECT * FROM T fails with "no such table". The usual exam answer is "TRUNCATE cannot be rolled back", which holds for Oracle and MySQL.
9. Views
A view is a stored SELECT that behaves like a virtual table. It stores no data of its own, so it always shows the current rows.
CREATE VIEW dept_summary AS
SELECT dept_id, COUNT(*) AS staff, MAX(salary) AS top_salary
FROM Employee GROUP BY dept_id;
Dept 10 shows staff 3, top_salary 50000; after UPDATE Employee SET salary = 55000 WHERE emp_id = 2 the same view shows 55000 without being changed. Views hide columns (security) and save repeated joins. Table vs view: a table stores data; a view stores only its query. A view built with GROUP BY or aggregates cannot be updated; SQLite makes every view read-only unless an INSTEAD OF trigger is defined. To change a view's query use CREATE OR REPLACE VIEW (MySQL, Oracle, PostgreSQL) or ALTER VIEW … AS SELECT … (MySQL, SQL Server); in Oracle, ALTER VIEW only recompiles the view or changes its constraints.
10. Classic exam queries
Worked example 3: the second highest salary. Salaries: 60000, 50000, 40000, 40000, 30000, NULL.
-- Method 1: works in every SQL dialect
SELECT MAX(salary) AS second_highest
FROM Employee
WHERE salary < (SELECT MAX(salary) FROM Employee);
- The inner query finds the highest salary, 60000.
- WHERE keeps salaries below it: 50000, 40000, 40000, 30000.
- MAX of those = 50000.
The equivalent WHERE salary NOT IN (SELECT MAX(salary) FROM Employee) also gives 50000.
-- Method 2: LIMIT/OFFSET (MySQL, PostgreSQL, SQLite); skip 1 distinct value, take 1
SELECT DISTINCT salary FROM Employee ORDER BY salary DESC LIMIT 1 OFFSET 1;
-- Method 3: N-th highest with a window function (SQL:2003; MySQL 8+, Oracle, SQLite 3.25+)
SELECT name, salary FROM (
SELECT name, salary, DENSE_RANK() OVER (ORDER BY salary DESC) AS rnk
FROM Employee WHERE salary IS NOT NULL
) ranked
WHERE rnk = 3;
Method 2 gives 50000; method 3 with rnk = 3 gives Karim 40000 and Nadia 40000 (ties share a rank). Two details: use DISTINCT with OFFSET, or ties shift the answer; and if every row has the same salary, method 1 returns one row containing NULL while method 2 returns no row. Oracle 12c+ and SQL Server 2012+ write OFFSET 1 ROWS FETCH NEXT 1 ROWS ONLY (older Oracle: ROWNUM; SQL Server also has TOP) instead of LIMIT … OFFSET.
Count per group, including empty groups.
SELECT d.dept_name, COUNT(e.emp_id) AS staff
FROM Department d
LEFT JOIN Employee e ON e.dept_id = d.dept_id
GROUP BY d.dept_id, d.dept_name
ORDER BY d.dept_id;
| dept_name | staff |
|---|---|
| CSE | 3 |
| EEE | 2 |
| HR | 0 |
| Audit | 0 |
With COUNT() instead, HR and Audit show 1, because the LEFT JOIN gives each of them one row (full of NULLs) and COUNT() counts rows. COUNT(e.emp_id) skips the NULL.
Department name with maximum and average salary (an inner join, so only departments with staff appear): CSE 50000 / 45000.0, EEE 60000 / 50000.0.
Duplicates: SELECT salary, COUNT(*) FROM Employee GROUP BY salary HAVING COUNT(*) > 1; → 40000, 2. The same pattern with name finds duplicate names.
11. Where SQLite differs from standard SQL and MySQL
| Feature | Standard SQL / MySQL | SQLite (tested, 3.50.4) |
|---|---|---|
| ANY / ALL subqueries | Supported | Syntax error: use MIN / MAX |
| TRUNCATE TABLE | Supported (DDL) | Syntax error: use DELETE FROM t |
| GRANT / REVOKE | Supported | Not implemented (file permissions instead) |
| RIGHT and FULL OUTER JOIN | Standard and most DBMSs; MySQL has no FULL JOIN (use LEFT JOIN UNION RIGHT JOIN) | Supported since 3.39 |
| Alias in WHERE | Error | Allowed: WHERE yearly > 500000 worked |
| Column not in GROUP BY | Error unless the column is functionally dependent on the GROUP BY columns (MySQL with ONLY_FULL_GROUP_BY, the default since 5.7.5) | Allowed: takes the value from one row of the group |
| 7 / 2 | MySQL 3.5000 | 3 (integer division; 7 / 2.0 gives 3.5) |
| ROUND(232.42, −2) | 200 (MySQL, Oracle) | 232.0 (a negative digit count is treated as 0) |
| Foreign keys | Always enforced (MySQL InnoDB) | Only after PRAGMA foreign_keys = ON |
| LIKE 'r%' | Case depends on collation (MySQL default: case-insensitive) | Case-insensitive for ASCII: matched Rafiq |
Joining strings also differs: SQLite, Oracle and PostgreSQL write 'Riaz' || ' (CSE)' (SQLite printed "Riaz (CSE)"), while MySQL uses CONCAT('Riaz', ' (CSE)'), because in MySQL the double bar means OR by default.
12. Tricky exam cases
- 10 records, unique non-NULL salaries.
SELECT COUNT(*) FROM Employee WHERE SALARY > ANY (SELECT SALARY FROM Employee)prints 9: every salary except the lowest beats at least one value. With > ALL it prints 0: no salary is greater than itself. (Checked with the MIN and MAX forms in SQLite: 9 and 0.) - NOT IN with a NULL.
SELECT dept_name FROM Department WHERE dept_id NOT IN (SELECT dept_id FROM Employee)returns 0 rows, not HR and Audit, because Tanvir's NULL dept_id makes every NOT IN test unknown. AddWHERE dept_id IS NOT NULLinside, or use NOT EXISTS. - ROUND with negative digits. ROUND(45.926, −1) = 50 and ROUND(232.420, −2) = 200 in Oracle and MySQL (the digits count leftwards from the decimal point).
- WHERE vs HAVING. WHERE filters rows before grouping and cannot hold COUNT, SUM, AVG; HAVING filters groups after. Aggregates may appear in SELECT, HAVING and ORDER BY, and inside a subquery in WHERE, but never directly in WHERE.
- UPDATE or DELETE without WHERE changes every row.
- Index.
CREATE INDEX idx_emp_dept ON Employee(dept_id)lets the DBMS search instead of scanning (SQLite's plan: "SEARCH Employee USING INDEX idx_emp_dept"), but it costs space and slows INSERT and UPDATE, so it does not always make an application faster. In most DBMSs a PRIMARY KEY or UNIQUE constraint creates an index automatically. - Transactions. A transaction ends with COMMIT (keep the changes) or ROLLBACK (undo them); SAVEPOINT marks a point to roll back to part-way.
Practice · অনুশীলন
- Using the sample tables, write a query showing each department name with the average salary of its employees. What does it return?
Answer
SELECT d.dept_name, AVG(e.salary) FROM Employee e JOIN Department d ON e.dept_id = d.dept_id GROUP BY d.dept_name; It returns CSE 45000 (Mitu's NULL salary is ignored) and EEE 50000. HR and Audit do not appear because the inner join drops departments with no employees.
- Write a query for the third highest distinct salary from Employee(emp_id, name, salary) without LIMIT or window functions.
Answer
SELECT DISTINCT e1.salary FROM Employee e1 WHERE 2 = (SELECT COUNT(DISTINCT e2.salary) FROM Employee e2 WHERE e2.salary > e1.salary); Exactly 2 distinct salaries are higher than the third highest. On the sample data it returns 40000.
- Table A has 5 rows and table B has 3 rows. How many rows does A CROSS JOIN B return, and how many columns?
Answer
5 × 3 = 15 rows; the number of columns is the columns of A plus the columns of B.
- Give the SQL to find employees who earn more than their managers in Employee(emp_id, name, salary, manager_id).
Answer
SELECT e.name FROM Employee e JOIN Employee m ON e.manager_id = m.emp_id WHERE e.salary > m.salary; This is a self join. On the sample data it returns Salma (60000 against Rafiq's 50000).
- Classify CREATE, UPDATE, GRANT, ROLLBACK, TRUNCATE and SELECT.
Answer
CREATE: DDL. UPDATE: DML. GRANT: DCL. ROLLBACK: TCL. TRUNCATE: DDL. SELECT: DQL, or DML in books that use only three groups.
Asked in past exams · আগের পরীক্ষায় যেভাবে এসেছে
Our past papers have 94 questions on this topic (40 MCQ, 54 written) from 72 exams. Here are 12 of them; each links to its full paper.
Which clause is executed first in an SQL query?
- a)WHERE
- b)SELECT
- c)FROM (correct answer)
- d)ORDER BY
Explanation · ব্যাখ্যা
Correct answer: (c) FROM
A query is written SELECT … FROM … WHERE … ORDER BY, but it is evaluated in a different logical order. The engine first needs the rows to work on, so the FROM clause (with its joins) is processed first. Then WHERE filters rows, GROUP BY and HAVING form and filter groups, SELECT computes the output columns, and ORDER BY sorts the result:
FROM → WHERE → GROUP BY → HAVING → SELECT → DISTINCT → ORDER BY
This is the logical (binding) order. The optimiser may choose a different physical plan, but the result must be the same as if this order were followed.
Example: in
SELECT district, COUNT(*) FROM applicants WHERE age < 30 GROUP BY district HAVING COUNT(*) > 5 ORDER BY district, the engine starts from the applicants table, keeps the under-30 rows, groups them by district, drops districts with five or fewer, and only then builds the output and sorts it.Why the other options are wrong
- (a) WHERE: It comes second; it filters the rows that FROM has produced, so it cannot run before them.
- (b) SELECT: It is evaluated after WHERE, GROUP BY and HAVING. That is why a column alias defined in SELECT cannot be used in WHERE in standard SQL.
- (d) ORDER BY: It comes last (only TOP/LIMIT/OFFSET follow it), which is why ORDER BY can use a SELECT alias.
Tip: Logical order starts with FROM and ends with ORDER BY, whatever the written order.
Sources: SELECT (Transact-SQL) - Microsoft Learn; SELECT - PostgreSQL Documentation; Problems with Column Aliases - MySQL 8.4 Reference Manual
What are the limitations of DBMS and how to related newsql with SQL and No-SQL.
Where is data warehousing used?
- a)Transaction System
- b)Logical system
- c)Decision support system (correct answer)
- d)None
Explanation · ব্যাখ্যা
Correct answer: (c) Decision support system
A data warehouse consolidates historical data from many operational sources into one integrated, read-mostly store designed for query and analysis. Managers and analysts run reports, OLAP and data mining on it to understand trends and make decisions, which is exactly what a decision support system (DSS) does. The warehouse is the data foundation of a DSS / business-intelligence environment.
Why the other options are wrong
- (a) Transaction System: Day-to-day transactions (orders, payments) run on OLTP databases that handle many small inserts and updates and keep current data. A warehouse is deliberately separated from this workload and is loaded in bulk by ETL.
- (b) Logical system: Not a recognised category of information system; it does not describe where a warehouse is used.
- (d) None: Wrong, because (c) is a correct use.
Tip: OLTP runs the business; the data warehouse (OLAP / DSS) helps decide about the business.
Sources: Introduction to Data Warehousing Concepts | Oracle Database 19c Data Warehousing Guide; What is a data warehouse? | IBM
- Written · 2023DESCO; Assistant Engineer; Exam: 20.05.2023 (DESCO)
What are the different types of join in SQL?
Which one of the following sorts rows in SQL?
- a)SORT BY
- b)ALIGN BY
- c)ORDER BY (correct answer)
- d)GROUP BY
Explanation · ব্যাখ্যা
Correct answer: (c) ORDER BY
ORDER BY sorts the rows of a query result, ascending (ASC) by default or descending with DESC. Without it, rows come back in whatever order the engine finds fastest, so no order is guaranteed.
SELECT name FROM employee ORDER BY name; -- Anik, Riaz, Toha SELECT name FROM employee ORDER BY name DESC; -- Toha, Riaz, AnikWhy the other options are wrong
- (a) SORT BY: Not an SQL clause; SQLite rejected it with a syntax error near "BY".
- (b) ALIGN BY: Not an SQL clause either; also a syntax error.
- (d) GROUP BY: It collects rows with equal values into one row per group for aggregates such as COUNT or SUM. It does not guarantee any output order; add ORDER BY when order matters.
Tip: Sort → ORDER BY; summarise per group → GROUP BY.
Sources: Sorting Rows (ORDER BY) - PostgreSQL Documentation; SELECT - PostgreSQL Documentation
Table Employee has 10 records. It has a non-NULL SALARY column which is also UNIQUE. The SQL statement
SELECT COUNT(*) FROM Employee WHERE SALARY > ANY (SELECT SALARY FROM EMPLOYEE);prints
- a)0
- b)5
- c)9 (correct answer)
- d)10
Explanation · ব্যাখ্যা
Correct answer: (c) 9
x > ANY (subquery)is true when x is greater than at least one value the subquery returns.- The subquery returns all 10 salaries, and they are all different (UNIQUE, NOT NULL).
- Every salary except the lowest is greater than at least the lowest salary, so the test is true for those 9 rows.
- The lowest salary is not greater than any value (only equal to itself), so that one row fails.
COUNT(*)= 10 − 1 = 9.
SQLite does not support
ANY, so the logic was run with an equivalent form on 10 unique salaries:SELECT COUNT(*) FROM Employee WHERE SALARY > (SELECT MIN(SALARY) FROM Employee); -- returns 9For example, with salaries of 18,000 to 27,000 taka in steps of 1,000, only the 18,000-taka row fails the test; the other 9 rows are counted.
Why the other options are wrong
- (a) 0: That is the result of
> ALL, where no salary can beat its own value. - (b) 5: Nothing in the query compares with a middle value; only the single minimum is excluded.
- (d) 10: The lowest salary has nothing smaller to beat, so all 10 cannot qualify.
Tip:
> ANY→ all rows except the minimum (n − 1 with unique values);> ALL→ 0 rows when the list includes every value.(a) Distinguish between table and view in database management system.
What is Indexing? Write down the usages of Indexing.
- Written · 2018NWPGCL — Assistant Engineer (CSE) Written Test: 2018
What are the difference among DDL, DML and DCL?
The SQL statement that retrieves or reads data from the table is-
- a)Select (correct answer)
- b)Read
- c)Query
- d)None of the above
Explanation · ব্যাখ্যা
Correct answer: (a) Select
SELECT is the SQL statement that retrieves rows from one or more tables or views:
SELECT * FROM staff;In SQLite, SELECT returned the table's rows, while
READ staffandQUERY staffwere rejected as syntax errors.Why the other options are wrong
- (b) Read: SQL has no READ statement; reading is done with SELECT.
- (c) Query: "query" is the general name for any request for data (a SELECT is a query), but QUERY is not an SQL statement.
- (d) None of the above: SELECT does exactly what is asked, so this does not apply.
Tip: Reading data = SELECT; changing data = INSERT, UPDATE, DELETE.
Source: PostgreSQL Documentation: SELECT
- Written · 2016Bangladesh Bank; Assistant Programmer Written Test: 2016
Define 'integrity rules' of database systems. Write a SQL query to get the second highest salary from Employee table.
What is the full meaning of SQL?
- a)Search and Query Language
- b)Simulation of Query Language
- c)Standard Query Language
- d)Structured Query Language (correct answer)
Explanation · ব্যাখ্যা
Correct answer: (d) Structured Query Language
SQL stands for Structured Query Language, the standardized language for defining, querying and changing data in relational databases. It is used by MySQL, Oracle, SQL Server, PostgreSQL and others, and is pronounced "S-Q-L" or "sequel".
Why the other options are wrong
- (a) Search and Query Language: not the expansion; SQL does far more than search (it also defines tables and changes data).
- (b) Simulation of Query Language: a made-up expansion with no meaning.
- (c) Standard Query Language: tempting because SQL is an ISO standard (ISO/IEC 9075), but the "S" stands for Structured, not Standard.
Tip: SQL = Structured Query Language; it is a standard, but "Standard" is not its name.
Sources: IBM i documentation: Structured Query Language; IBM: What Is Structured Query Language (SQL)?; PostgreSQL Documentation: Appendix D. SQL Conformance
Common mistakes · সাধারণ ভুল
- Putting an aggregate in WHERE (WHERE COUNT(*) > 2): aggregates belong in HAVING.
- Writing salary = NULL instead of salary IS NULL: the comparison is never true, so no rows come back.
- Dividing by all rows when computing AVG by hand: AVG ignores NULLs, so it divides by the non-NULL count.
- Calling TRUNCATE a DML command: it is DDL, removes all rows, takes no WHERE and (in Oracle and MySQL) cannot be rolled back.
- Saying UNION keeps duplicates: UNION removes them, UNION ALL keeps them.
- Using COUNT(*) after a LEFT JOIN to count children: empty groups show 1 instead of 0; count a column from the right table.
বাংলায় সংক্ষেপে
- এসকিউএল-এর পূর্ণরূপ Structured Query Language; এটি রিলেশনাল ডেটাবেজের প্রমিত ডিক্লারেটিভ ভাষা।
- ডিডিএল: CREATE, ALTER, DROP, TRUNCATE; ডিএমএল: INSERT, UPDATE, DELETE (SELECT-কে ডিকিউএল বা ডিএমএল ধরা হয়); ডিসিএল: GRANT, REVOKE; টিসিএল: COMMIT, ROLLBACK, SAVEPOINT।
- যৌক্তিক ক্রম: FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY; তাই সবার আগে FROM কার্যকর হয়।
- WHERE সারি ছাঁকে, HAVING গ্রুপ ছাঁকে; অ্যাগ্রিগেট ফাংশন (COUNT, SUM, AVG, MAX, MIN) সরাসরি WHERE-এ চলে না (WHERE-এর সাবকোয়েরির ভেতরে চলে), এবং COUNT(*) ছাড়া বাকি সব অ্যাগ্রিগেট ফাংশন NULL বাদ দেয়।
- INNER JOIN শুধু মিলে যাওয়া সারি দেয়; LEFT, RIGHT ও FULL OUTER JOIN না-মেলা সারি NULL সহ রাখে; CROSS JOIN দেয় m × n সারি।
- DELETE (ডিএমএল, WHERE চলে, রোলব্যাক করা যায়), TRUNCATE (ডিডিএল, সব সারি মোছে, কাঠামো থাকে), DROP (পুরো টেবিল মুছে ফেলে)।
- দ্বিতীয় সর্বোচ্চ বেতন: SELECT MAX(salary) FROM Employee WHERE salary < (SELECT MAX(salary) FROM Employee);
Sources
- ISO/IEC 9075-2:2023, Information technology: Database languages SQL, Part 2: Foundation (SQL/Foundation)
- SQLite documentation: SELECT
- SQLite documentation: SQL Features That SQLite Does Not Implement
- MySQL 8.4 Reference Manual: SELECT Statement
- PostgreSQL 18 Documentation: Table Expressions (FROM, WHERE, GROUP BY, HAVING)
- Oracle Database 19c SQL Language Reference: TRUNCATE TABLE
- Oracle Database 19c SQL Language Reference: Types of SQL Statements
- MySQL 8.4 Reference Manual: TRUNCATE TABLE Statement
- MySQL 8.4 Reference Manual: Set Operations with UNION, INTERSECT, and EXCEPT
- MySQL 8.4 Reference Manual: Subqueries with ALL
- PostgreSQL Documentation: TRUNCATE
- Microsoft Learn: TRUNCATE TABLE (Transact-SQL)
Updated 2026-10-18. Written by ARBS Academy; the past exam questions are from public recruitment exams.