SQL Programming Resources
Find top SQL resources from global universities, cool projects, and learning materials for data analytics. Admin: @coderfun Useful links: heylink.me/DataAnalytics Promotions: @love_data
Mostrar más📈 Análisis del canal de Telegram SQL Programming Resources
El canal SQL Programming Resources (@sqlanalyst) en el segmento lingüístico de Inglés es un actor destacado. Actualmente la comunidad reúne a 76 715 suscriptores, ocupando la posición 1 645 en la categoría Tecnologías y Aplicaciones y el puesto 4 014 en la región India.
📊 Métricas de audiencia y dinámica
Desde su creación el невідомо, el proyecto ha mostrado un crecimiento acelerado, reuniendo a 76 715 suscriptores.
Según los últimos datos del 05 octubre, 2026, el canal mantiene una actividad estable. En los últimos 30 días la variación de miembros fue de 60, y en las últimas 24 horas de -2, conservando un alto alcance.
- Estado de verificación: No verificado
- Tasa de interacción (ER): El promedio de interacción de la audiencia es 1.36%. Durante las primeras 24 horas tras publicar, el contenido suele obtener 0.79% de reacciones respecto al total de suscriptores.
- Alcance de las publicaciones: Cada publicación recibe en promedio 1 044 visualizaciones. En el primer día suele acumular 607 visualizaciones.
- Reacciones e interacción: La audiencia responde de forma activa: el promedio de reacciones por publicación es 3.
- Intereses temáticos: El contenido se centra en temas clave como row, sql, customer_id, logic, desc.
📝 Descripción y política de contenido
El autor describe el recurso como un espacio para expresar opiniones subjetivas:
“Find top SQL resources from global universities, cool projects, and learning materials for data analytics.
Admin: @coderfun
Useful links: heylink.me/DataAnalytics
Promotions: @love_data”
Gracias a la alta frecuencia de actualizaciones (últimos datos recibidos el 06 octubre, 2026), el canal mantiene la vigencia y un amplio alcance. La analítica demuestra que la audiencia interactúa activamente con el contenido, lo que lo convierte en un punto de referencia dentro de la categoría Tecnologías y Aplicaciones.
employee_id | employee_name | email
------------|---------------|-------------------
1 | Amit | amit@gmail.com
2 | Rahul | rahul@gmail.com
3 | Priya | amit@gmail.com
4 | Neha | neha@gmail.com
5 | Raj | rahul@gmail.com
Expected result:
email
amit@gmail.com
rahul@gmail.com
💡 Approach
We need to:
1️⃣ Group records by email.
2️⃣ Count how many times each email appears.
3️⃣ Keep only the emails whose count is greater than 1.
📌 SQL Solution
SELECT email, COUNT(*) AS occurrence_count
FROM Employee
GROUP BY email
HAVING COUNT(*) > 1;
🔎 Why use HAVING instead of WHERE?
"WHERE" filters individual rows before grouping.
"HAVING" filters groups after "GROUP BY".
Since we want to filter based on "COUNT(*)", we use "HAVING".
GROUP BY email
HAVING COUNT(*) > 1
This means:
"Group employees by email and return only those groups containing more than one record."
🎯 Double Tap ❤️ For Part-3SELECT MAX(salary) AS second_highest_salary
FROM Employee
WHERE salary < (
SELECT MAX(salary)
FROM Employee
);
Output:
second_highest_salary
80000
🔎 Why does this work?
The inner query:
SELECT MAX(salary)
FROM Employee;
returns:
90000
Then the outer query considers only salaries below 90000:
50000
70000
80000
80000
Finally, MAX() returns:
80000
⚠️ Important Interview Point
If the question asks for the second-highest DISTINCT salary, this approach works because duplicate salaries are naturally treated as one value.
For example:
90000
80000
80000
70000
The second-highest distinct salary is still 80000.
💯 Double Tap ❤️ For Part-2SELECT MAX(salary) AS SecondHighest
FROM Employees
WHERE salary < (SELECT MAX(salary) FROM Employees);
2. Find employees without assigned managers
SELECT * FROM Employees
WHERE manager_id IS NULL;
3. Retrieve departments with more than 5 employees
SELECT department_id, COUNT(*) AS employee_count
FROM Employees
GROUP BY department_id
HAVING COUNT(*) > 5;
4. List customers who made no orders
SELECT c.name
FROM Customers c
LEFT JOIN Orders o ON c.id = o.customer_id
WHERE o.id IS NULL;
5. Find the top 3 highest-paid employees
SELECT * FROM Employees
ORDER BY salary DESC
LIMIT 3;
6. Display total sales for each product
SELECT product, SUM(amount) AS total_sales
FROM Sales
GROUP BY product;
7. Get employee names starting with 'A' and ending with 'n'
SELECT name FROM Employees
WHERE name LIKE 'A%n';
8. Show employees who joined in the last 30 days
SELECT * FROM Employees
WHERE join_date >= CURRENT_DATE - INTERVAL 30 DAY;
💬 Tap ❤️ for more!BEGIN;
INSERT INTO orders (order_id, customer_id, order_amount)
VALUES (1001, 101, 5000);
INSERT INTO order_items (order_id, product_id, quantity)
VALUES (1001, 501, 2);
UPDATE products
SET stock_quantity = stock_quantity - 2
WHERE product_id = 501
AND stock_quantity >= 2;
COMMIT;
In a real application, you would also validate that each critical operation succeeded and handle errors according to the database/application's transaction mechanism.
If a critical operation fails:
ROLLBACK;
🎯 Key Takeaway
Remember:
• TRANSACTION → Group related operations into one unit
• COMMIT → Save changes
• ROLLBACK → Undo uncommitted changes
• SAVEPOINT → Create a rollback point
• ACID → Atomicity → Consistency → Isolation → Durability
The most important practical lesson:
«Before making large UPDATE or DELETE changes, first run the corresponding SELECT and verify exactly which rows will be affected.»
Transactions help protect data, but safe SQL also depends on careful query design, validation, permissions, and understanding your database's transaction behavior.
Double Tap ❤️ For More
-----
3.11 ₽ · /balance_helpBEGIN;
UPDATE customers
SET status = 'Active'
WHERE customer_id = 101;
SAVEPOINT s1;
UPDATE customers
SET status = 'Inactive'
WHERE customer_id = 102;
ROLLBACK TO SAVEPOINT s1;
COMMIT;
The first update can remain while the second update is rolled back, subject to the database's transaction semantics.
30️⃣ Common Mistakes
❌ Mistake 1: Forgetting COMMIT — You may make changes but not persist them as intended.
❌ Mistake 2: Assuming ROLLBACK always works — If the changes have already been committed, a normal rollback cannot undo them.
❌ Mistake 3: Running UPDATE without checking the WHERE condition — Dangerous:
UPDATE customers SET status = 'Inactive';
Safer workflow:
SELECT * FROM customers WHERE ...;
UPDATE customers SET status = 'Inactive' WHERE ...;
❌ Mistake 4: Assuming transaction behavior is identical everywhere — Database systems differ in areas such as:
- Autocommit
- DDL transactions
- Isolation
- Locking
- Savepoints
- Error handling
🎯 Interview Questions
•
Q1. What is a transaction? A transaction is a logical unit of one or more database operations that are handled together.
•
Q2. What does COMMIT do? It commits the transaction's changes.
•
Q3. What does ROLLBACK do? It reverses uncommitted changes in the transaction.
•
Q4. What is SAVEPOINT? A savepoint marks a point inside a transaction to which you can potentially roll back without undoing the entire transaction.
•
Q5. What does ACID stand for?
A → Atomicity,
C → Consistency,
I → Isolation,
D → Durability
•
Q6. What is atomicity? It treats the transaction as a logical unit so that its operations are committed together or rolled back as appropriate.
•
Q7. What is isolation? It controls how concurrent transactions interact and what changes they can see.
•
Q8. What is durability? Committed changes are intended to survive failures according to the database's durability mechanisms.
•
Q9. What is autocommit? A mode where individual statements may be committed automatically.
•
Q10. What is a dirty read? Reading data changed by another transaction before that transaction commits.
🧠 Practice Questions
Practice 1 Write a transaction that updates a customer's status and commits it.
BEGIN;
UPDATE customers SET status = 'Active' WHERE customer_id = 101;
COMMIT;
Practice 2 Update a customer's status but roll back the change.
BEGIN;
UPDATE customers SET status = 'Inactive' WHERE customer_id = 101;
ROLLBACK;
Practice 3 Create a savepoint after the first update.
BEGIN;
UPDATE customers SET status = 'Active' WHERE customer_id = 101;
SAVEPOINT customer_update;
UPDATE customers SET status = 'Inactive' WHERE customer_id = 102;
ROLLBACK TO SAVEPOINT customer_update;
COMMIT;
Practice 4 Before executing this UPDATE:
UPDATE orders SET status = 'Cancelled' WHERE order_date < DATE '2025-01-01';
write a SELECT that lets you inspect the affected records.
SELECT * FROM orders WHERE order_date < DATE '2025-01-01';
Practice 5 Explain what happens here:
BEGIN;
UPDATE accounts SET balance = balance - 5000 WHERE account_id = 101;
UPDATE accounts SET balance = balance + 5000 WHERE account_id = 202;
ROLLBACK;SELECT * FROM customers;
A transaction is a logical unit containing one or more operations.
For example:
Transaction
│
├── INSERT
├── UPDATE
├── UPDATE
└── COMMIT
So:
• Query → Individual SQL operation
• Transaction → Unit of work containing one or more operations
28️⃣ Real-World Analytics Example
Suppose an operations team needs to correct payment statuses.
There are 10,000 affected records.
Instead of blindly running:
UPDATE payments
SET status = 'Completed'
WHERE payment_date IS NOT NULL;
first inspect:
SELECT payment_id, status, payment_date
FROM payments
WHERE payment_date IS NOT NULL;
Then, if the correction is confirmed:
BEGIN;
UPDATE payments
SET status = 'Completed'
WHERE payment_date IS NOT NULL;
SELECT COUNT(*) AS updated_rows
FROM payments
WHERE payment_date IS NOT NULL
AND status = 'Completed';
COMMIT;
If the validation reveals an unexpected result:
ROLLBACK;ROLLBACK;
If everything is correct:
COMMIT;
This can be useful when performing potentially dangerous data modifications.
1️⃣8️⃣ A Safe Pattern for Data Changes
Before executing a large UPDATE or DELETE, analysts often first run a SELECT using the same condition.
Instead of immediately doing:
UPDATE customers
SET status = 'Inactive'
WHERE last_order_date < DATE '2024-01-01';
first check:
SELECT *
FROM customers
WHERE last_order_date < DATE '2024-01-01';
Then, where transaction support and operational rules permit:
BEGIN;
UPDATE customers
SET status = 'Inactive'
WHERE last_order_date < DATE '2024-01-01';
-- Verify the affected rows
COMMIT;
If something looks wrong:
ROLLBACK;
This is a valuable habit when working with production data.
1️⃣9️⃣ Transactions and Autocommit
Many database clients use an autocommit mode.
When autocommit is enabled, individual statements may be committed automatically.
For example:
UPDATE customers
SET status = 'Active'
WHERE customer_id = 101;
may be committed immediately.
That means you may not be able to simply run:
ROLLBACK;
after the statement has already been committed.
The exact behavior depends on:
• Database system
• Client/tool
• Connection settings
• Transaction configuration
Always understand the transaction mode before modifying production data.
20️⃣ Transactions and DDL
Statements such as:
• CREATE
• ALTER
• DROP
are DDL statements.
Their transaction behavior varies significantly across database systems.
Some databases implicitly commit certain DDL operations.
Therefore, don't assume:
BEGIN;
DROP TABLE test_table;
ROLLBACK;CHECK (balance >= 0)
An operation that violates the constraint may fail rather than leaving the database in an invalid state.
1️⃣2️⃣ Isolation
Isolation deals with how concurrent transactions interact with each other.
Imagine Transaction A + Transaction B both accessing the same data at the same time.
The database needs rules governing what each transaction can see while the other is running.
This becomes especially important in:
• Banking
• Payments
• Order processing
• Inventory systems
• Financial systems
• High-volume applications
1️⃣3️⃣ Durability
Once a transaction has successfully committed, its changes are intended to survive subsequent failures according to the database's durability guarantees.
Conceptually:
COMMIT ↓ Data saved ↓ System failure ↓ Committed changes remain
Durability is supported by database mechanisms such as transaction logs and recovery systems.
1️⃣4️⃣ Transaction Example — Bank Transfer
Suppose:
• Account 101 → ₹50,000
• Account 202 → ₹30,000
• Transfer: ₹5,000
SQL:
BEGIN;
UPDATE accounts
SET balance = balance - 5000
WHERE account_id = 101;
UPDATE accounts
SET balance = balance + 5000
WHERE account_id = 202;
COMMIT;
After success:
• Account 101 → ₹45,000
• Account 202 → ₹35,000
• The total money remains: ₹80,000
1️⃣5️⃣ What If Something Fails?
Suppose the second update fails.
Without appropriate transaction handling:
• Account 101 ₹50,000 → ₹45,000
• Account 202 Still ₹30,000
The system has become inconsistent.
With a transaction:
BEGIN ↓ Debit Account 101 ↓ Credit Account 202 ❌ ↓ ROLLBACK
The debit can be rolled back along with the other uncommitted changes.
1️⃣6️⃣ Transactions with INSERT
Transactions aren't limited to UPDATE.
Example:
BEGIN;
INSERT INTO orders (order_id, customer_id, order_amount)
VALUES (1001, 101, 5000);
INSERT INTO order_items (order_id, product_id, quantity)
VALUES (1001, 501, 2);
COMMIT;
Both operations belong to the transaction.
1️⃣7️⃣ Transactions with DELETE
You can also use transactions before deleting records.
For example:
BEGIN;
DELETE FROM orders
WHERE order_date < DATE '2020-01-01';
Before committing, you can inspect the result.
If it isn't what you expected:BEGIN TRANSACTION;
-- or
BEGIN;
Some database systems handle transaction boundaries differently, so exact syntax varies.
For example:
BEGIN;
UPDATE accounts
SET balance = balance - 1000
WHERE account_id = 101;
The transaction has started.
4️⃣ COMMIT
"COMMIT" permanently saves the changes made during the transaction.
Example:
BEGIN;
UPDATE accounts
SET balance = balance - 1000
WHERE account_id = 101;
UPDATE accounts
SET balance = balance + 1000
WHERE account_id = 202;
COMMIT;
After the transaction is successfully committed, the changes become durable according to the database's transaction rules.
5️⃣ ROLLBACK
"ROLLBACK" reverses uncommitted changes within the transaction.
Example:
BEGIN;
UPDATE accounts
SET balance = balance - 1000
WHERE account_id = 101;
UPDATE accounts
SET balance = balance + 1000
WHERE account_id = 202;
ROLLBACK;
The changes made in that transaction are undone.
6️⃣ COMMIT vs ROLLBACK
This is a common interview question.
• COMMIT → Save the transaction
• ROLLBACK → Undo uncommitted changes
Example:
BEGIN;
UPDATE customers
SET status = 'Inactive'
WHERE customer_id = 101;
COMMIT;
The change is committed.
Whereas:
BEGIN;
UPDATE customers
SET status = 'Inactive'
WHERE customer_id = 101;
ROLLBACK;
The uncommitted update is rolled back.
7️⃣ SAVEPOINT
Sometimes you don't want to roll back the entire transaction.
You can create a "SAVEPOINT".
Example:
BEGIN;
UPDATE customers
SET status = 'Active'
WHERE customer_id = 101;
SAVEPOINT customer_update;
UPDATE customers
SET status = 'Inactive'
WHERE customer_id = 102;
Now suppose you don't want the second update.
You can roll back to the savepoint:
ROLLBACK TO SAVEPOINT customer_update;EXPLAIN
SELECT *
FROM orders
WHERE customer_id = 101;
If supported by your database:
EXPLAIN ANALYZE
SELECT *
FROM orders
WHERE customer_id = 101;
🔥 Mini Challenge
You have an "orders" table containing 50 million
rows:
• order_id
• customer_id
• order_date
• status
• region
• order_amount
The following query is running slowly:
SELECT
order_id,
order_date,
order_amount
FROM orders
WHERE customer_id = 5001
AND order_date >= DATE '2026-01-01'
AND status = 'Completed';
Think about:
1. Which columns are being filtered?
2. Would a composite index be worth investigating?
3. Which column should come first?
4. Should you use "SELECT *"?
5. How would you inspect the execution plan?
6. Would the index always be used?
7. What happens to performance when the table receives millions of new rows?
Possible candidate to investigate:
CREATE INDEX idx_orders_customer_date
ON orders(customer_id, order_date);
Then inspect the query:
EXPLAIN
SELECT
order_id,
order_date,
order_amount
FROM orders
WHERE customer_id = 5001
AND order_date >= DATE '2026-01-01'
AND status = 'Completed';
Don't automatically assume this is the optimal index.
Use the execution plan, data distribution, workload, and database-specific behavior to determine whether it actually helps.
🎯 Key Takeaway
Remember:
INDEX → Helps the database find data efficiently
COMPOSITE INDEX → Index on multiple columns
EXPLAIN → Inspect how the database plans to execute a query
SELECTIVITY → How much a filter narrows the data
And the most important principle:
More indexes ≠ Always faster
Good indexing + Good query design + Execution-plan analysis = Better SQL performance
A strong Data Analyst doesn't just write SQL that produces the correct answer.
They also understand how that SQL behaves when the data grows from thousands of rows to millions or billions. 🚀
🎯 Double Tap ❤️ For More
-----
2.98 ₽ · /balance_helpSELECT * may be unnecessary.
Step 2
Can I filter earlier? WHERE can reduce the amount of data processed.
Step 3
Are JOIN conditions correct? Check: ON a.id = b.id
Step 4
Could a suitable index help? Look at frequently used WHERE, JOIN, ORDER BY columns.
Step 5
Is the index being used? Check the execution plan.
Step 6
Am I processing unnecessary rows? Look at the data volume.
Step 7
Are functions preventing efficient access? For example: WHERE UPPER(name) = ...
Step 8
Am I creating too many indexes? Indexes also have costs.
💼 Data Analyst Example
Imagine a dashboard queries:
SELECT
customer_id,
SUM(order_amount) AS total_sales
FROM orders
WHERE order_date >= DATE '2026-01-01'
GROUP BY customer_id;
The table contains:
100 million orders
Potential performance considerations include:
1. Is order_date indexed?
2. How selective is the date filter?
3. How many rows are processed?
4. Is partitioning available?
5. What does EXPLAIN show?
6. Is the aggregation expensive?
7. Is the dashboard requesting this data repeatedly?
A strong analyst doesn't immediately say:
«"Create an index."»
Instead, they investigate the execution plan and workload first.
🎯 Interview Questions
Q1. What is an index?
An index is a database structure that can help locate rows more efficiently.
Q2. Why are indexes useful?
They can improve read performance for suitable queries, especially when searching or joining on indexed columns.
Q3. Can indexes slow down INSERT operations?
Yes. The database may need to maintain indexes when rows are inserted.
Q4. Can indexes slow down UPDATE and DELETE?
Yes, depending on which indexed columns are affected and the database implementation.
Q5. What is a composite index?
An index containing multiple columns.
CREATE INDEX idx_customer_date
ON orders(customer_id, order_date);
Q6. Does the order of columns in a composite index matter?
Yes. The leading columns strongly influence which queries can efficiently use the index.
Q7. Does every query use an index if one exists?
No. The optimizer decides whether using an index is beneficial.
Q8. What is EXPLAIN?
It is a command or feature used to inspect a query's execution plan, with syntax varying by database.
Q9. What is selectivity?
It describes how effectively a condition narrows the number of matching rows.
Q10. Why shouldn't you index every column?
Indexes consume storage and require maintenance during data modifications, so excessive indexing can hurt write performance.
🧠 Practice Questions
Practice 1
Create an index on "customer_id":
CREATE INDEX idx_orders_customer_id
ON orders(customer_id);
Practice 2
Create a composite index using customer and date:
CREATE INDEX idx_orders_customer_date
ON orders(customer_id, order_date);
Practice 3
Create a unique index on email:
CREATE UNIQUE INDEX idx_customers_email
ON customers(email);
Practice 4
Write a query that could potentially benefit from an index on "customer_id":
SELECT
order_id,
order_date,
order_amount
FROM orders
WHERE customer_id = 101;
Practice 5
Inspect the execution plan:EXPLAIN
SELECT *
FROM orders
WHERE customer_id = 101;
This lets you inspect the planned execution strategy.
Some databases support:
EXPLAIN ANALYZE
which can provide information about actual execution as well.
Exact syntax and output vary by database.
26️⃣ Table Scan vs Index Access
Imagine a table with:
10,000,000 rows
A table scan may mean the database reads a large portion of the table to find matching records.
Conceptually:
10 million rows
↓
Check rows
↓
Find matching rows
An index-based access path may instead look more like:
Index
↓
Locate matching keys
↓
Fetch relevant rows
For highly selective queries, the second approach can be much more efficient.
But if a query needs a large percentage of the table, scanning the table may actually be more efficient.
This is why the optimizer chooses the execution strategy.
27️⃣ Selectivity
Selectivity describes how effectively a condition narrows down the data.
Consider:
WHERE customer_id = 100245
If customer IDs are unique, this may return one row.
Highly selective.
Now consider:
WHERE country = 'India'
If 60% of the table contains Indian customers, the condition is much less selective.
The database may decide that scanning the table is cheaper than using an index.
Therefore:
«An index isn't automatically useful simply because the column appears in WHERE.»
28️⃣ Indexes on Low-Cardinality Columns
Suppose:
status
contains only:
• Active
• Inactive
That's a low-cardinality column.
An index may not always provide a large benefit if most rows match the condition.
For example:
WHERE status = 'Active'
If 95% of rows are Active, reading the index and then retrieving almost the entire table may be less efficient than scanning the table.
Again, the optimizer makes the decision.
29️⃣ Real-World Example
Suppose an orders table contains:
50 million rows
Analysts frequently run:
SELECT
order_id,
order_date,
order_amount
FROM orders
WHERE customer_id = 12345
AND order_date >= DATE '2026-01-01';
A possible candidate is:
CREATE INDEX idx_orders_customer_date
ON orders(customer_id, order_date);SELECT *
FROM customers
WHERE UPPER(customer_name) = 'RAHUL';
If you have a normal index on:
customer_name
the database may not be able to use that index efficiently because the query applies a function to the column.
Depending on the database, an expression/function-based index may help:
CREATE INDEX idx_customer_upper_name
ON customers(UPPER(customer_name));
The exact syntax and availability depend on the database.
1️⃣7️⃣ Indexes and NULL
Indexes can have database-specific behavior regarding NULL values.
For example:
SELECT *
FROM customers
WHERE email IS NULL;
Whether and how an index can help depends on the database's index implementation.
Don't assume every database handles NULL indexing identically.
1️⃣8️⃣ Why Not Create an Index on Every Column?
This is a common beginner mistake.
You might think:
More indexes
Faster database
But that's not true.
Indexes have costs.
When data changes:
• INSERT
• UPDATE
• DELETE
the database may also need to maintain the relevant indexes.
Therefore:
More indexes
↓
More storage
↓
More maintenance
↓
Potentially slower writes
Indexes should be created based on actual query patterns and workload requirements.
1️⃣9️⃣ Indexes Have a Storage Cost
Suppose your table contains:
100 million rows
and you create several large indexes.
The indexes themselves can consume significant storage.
So database design involves a trade-off:
Read performance
↕
Write performance
↕
Storage
A good indexing strategy balances all three.
20️⃣ Query Performance
Indexes are only one part of SQL performance.
Other factors include:
• Query structure
• JOIN strategy
• Filtering
• Data volume
• Table design
• Statistics
• Partitioning
• Database engine
• Execution plan
• Network transfer
• Aggregations
• Sorting
• Data types
A slow query isn't automatically an "index problem."
21️⃣ SELECT * and Performance
Consider:
SELECT *
FROM orders
WHERE customer_id = 101;
If you only need:
• order_id
• order_date
• order_amount
prefer:
SELECT
order_id,
order_date,
order_amount
FROM orders
WHERE customer_id = 101;
Why?
Because retrieving unnecessary columns can:
• Increase data transfer
• Increase memory usage
• Increase I/O
• Make downstream processing heavier
It also makes your SQL less explicit.
22️⃣ Filter Early
Suppose you need sales for 2026:
SELECT
customer_id,
SUM(order_amount) AS total_sales
FROM orders
WHERE order_date >= DATE '2026-01-01'
GROUP BY customer_id;
Filtering before aggregation can significantly reduce the amount of data that needs to be processed.
Conceptually:
10 million rows
↓
Filter
↓
2 million rows
↓
Aggregate
instead of:
10 million rows
↓
Aggregate everything
↓
Filter later
The optimizer may transform queries internally, but writing clear predicates is still important.
23️⃣ Avoid Unnecessary Data Processing
Suppose you need only completed transactions:
SELECT
transaction_id,
amount
FROM transactions
WHERE status = 'Completed';