الدرس 1 · الوحدة 1: Practical SQL with SQLite
Your first query: SELECT, WHERE and ORDER BY on the orders table
- Pick the columns you want with SELECT
- Keep only the rows you want with WHERE
- Sort the result with ORDER BY
Why this matters
When a monthly export has hundreds of thousands of rows, Excel slows to a crawl: filters freeze, sorting takes ages, and you still have to copy the result somewhere clean. SQL lets you ask the data a question directly and get a short, sorted answer in a moment, the same way every time. This lesson covers the three words behind most everyday questions.
Key ideas
- SELECT is "which columns". You list the columns you want, separated by commas, and FROM names the table to read. A star (
*) means every column, which is handy for a quick look. - WHERE is "which rows". It works like Excel's filter arrow: only rows where your rule is true come back. Text values go in single quotes (
'shipped'), numbers do not, and AND or OR let you combine rules. - ORDER BY is "in what order". Results sort smallest first (A to Z for text) unless you add DESC for largest first. Without ORDER BY, SQL promises no order at all.
- Written order is not run order. You write SELECT, FROM, WHERE, ORDER BY, but the database reads the table first, filters with WHERE, then picks columns, then sorts. For example, on a small orders table:
SELECT customer, amount
FROM orders
WHERE status = 'shipped' AND amount > 80
ORDER BY amount DESC;
If the shipped orders are 45, 18, 60, 210 and 95 dollars, only 210 and 95 pass both rules, and 210 comes first.
Try it before you watch
The orders table has these amounts: Ana 45 (shipped), Ben 120 (pending), Chen 18 (shipped), Dina 75 (cancelled), Ana 60 (shipped), Omar 210 (shipped), Ben 32 (pending), Sara 95 (shipped). Which customers does this query return, and in what order?
SELECT customer, amount
FROM orders
WHERE amount < 50
ORDER BY amount;
Show answerHide answer
Chen (18), Ben (32), Ana (45). WHERE keeps the three orders under 50 of any status, and ORDER BY without DESC sorts smallest first. This shows that a rule on a number needs no quotes, and that ascending is the default.
Words to know
- database: a place where tables are stored together; in SQLite the whole database is one file on your computer.
- table: like one Excel sheet, but every column has a fixed name and every row follows the same layout.
- query: a question written in SQL; the database answers with a table of rows.
- SQLite: a free, small database that needs no server to install and comes built into Python.
- DESC: short for descending; used after ORDER BY to put the largest values first.
What to watch for
- In the worked example, watch the rows disappear before the columns are trimmed. That animation shows the run order from the Key ideas.
- Notice the common mistake near the end: writing
shippedwithout quotes makes SQLite look for a the header of a column in a table, like customer or amount and stop with an error. - Listen for the tip about dates written as year-month-day. It explains why sorting dates as text works in the final exercise.
Learn it with your tutor on the live board
أهم نقاط الفيديو
Your data is too big for Excel
- The shop exports 400,000 orders a month
- Excel slows down, filters take ages
- The manager wants shipped orders, biggest first
- SQL asks the database directly
What you will learn
- Pick the columns you want with SELECT
- Keep only the rows you want with WHERE
- Sort the result with ORDER BY
Meet SQLite
- A database: tables stored together in one file
- A table: like one sheet, with fixed columns
- A query: a question written in SQL
- SQLite: free, small, no server to install
The orders table
- One row per order
- Columns: id, order_date, customer, amount, status
- status is shipped, pending or cancelled
- Eight sample rows in this lesson
layout: wide
tables:
orders:
columns: [id, order_date, customer, amount, status]
rows:
- [101, "2026-01-03", Ana, 45, shipped]
- [102, "2026-01-04", Ben, 120, pending]
- [103, "2026-01-04", Chen, 18, shipped]
- [104, "2026-01-05", Dina, 75, cancelled]
- [105, "2026-01-06", Ana, 60, shipped]
- [106, "2026-01-07", Omar, 210, shipped]
- [107, "2026-01-08", Ben, 32, pending]
- [108, "2026-01-09", Sara, 95, shipped]
query: |
SELECT * FROM orders
steps:
- at: "just eight"
show: tables SELECT picks columns
- FROM names the table
- SELECT lists the columns, separated by commas
- SELECT star returns every column
SELECT customer, amount
FROM orders; WHERE filters rows
- Works like Excel's filter arrow
- Text goes in single quotes
- Compare numbers: amount > 50
- Combine rules with AND, OR
SELECT customer, amount, status
FROM orders
WHERE status = 'shipped'; ORDER BY sorts the result
- ASC: smallest first (the default)
- DESC: largest first
- Sort by several columns with commas
SELECT customer, amount
FROM orders
ORDER BY amount DESC; Worked example: all three together
- Shipped orders, biggest first
- Written order: SELECT, FROM, WHERE, ORDER BY
- Run order: FROM, WHERE, SELECT, ORDER BY
layout: wide
tables:
orders:
columns: [id, order_date, customer, amount, status]
rows:
- [101, "2026-01-03", Ana, 45, shipped]
- [102, "2026-01-04", Ben, 120, pending]
- [103, "2026-01-04", Chen, 18, shipped]
- [104, "2026-01-05", Dina, 75, cancelled]
- [105, "2026-01-06", Ana, 60, shipped]
- [106, "2026-01-07", Omar, 210, shipped]
- [107, "2026-01-08", Ben, 32, pending]
- [108, "2026-01-09", Sara, 95, shipped]
query: |
SELECT id, customer, amount
FROM orders
WHERE status = 'shipped'
ORDER BY amount DESC
steps:
- at: "the eight orders"
show: tables
- at: "type the full query"
show: query
- at: "only shipped orders survive"
show: where
- at: "keep three columns"
show: select
- at: "biggest amount on top"
show: order
- at: "five rows come back"
show: result Try it from Python
import sqlite3
con = sqlite3.connect(":memory:")
con.execute("CREATE TABLE orders (id, order_date, customer, amount, status)")
rows = [
(101, "2026-01-03", "Ana", 45, "shipped"),
(102, "2026-01-04", "Ben", 120, "pending"),
(103, "2026-01-04", "Chen", 18, "shipped"),
(104, "2026-01-05", "Dina", 75, "cancelled"),
(105, "2026-01-06", "Ana", 60, "shipped"),
(106, "2026-01-07", "Omar", 210, "shipped"),
(107, "2026-01-08", "Ben", 32, "pending"),
(108, "2026-01-09", "Sara", 95, "shipped"),
]
con.executemany("INSERT INTO orders VALUES (?, ?, ?, ?, ?)", rows)
query = """
SELECT customer, amount
FROM orders
WHERE amount > 50
ORDER BY amount DESC
"""
for row in con.execute(query):
print(row) Common mistake: text without quotes
- Without quotes, SQL looks for a column
- Error: no such column: shipped
- Text values need single quotes
WHERE status = shipped; -- error
WHERE status = 'shipped'; -- correct Recap
- SELECT chooses columns, FROM names the table
- WHERE keeps rows that match a rule
- ORDER BY sorts; DESC puts the largest first
Your exercise
- Use the eight-row orders table
- Show order_date, customer and amount
- Only pending orders
- Newest order first
- Check: two rows, Ben on 2026-01-08 on top
النص المكتوب
Your data is too big for Excel. Picture a Monday morning. Your manager asks for every shipped order from the online shop, sorted with the biggest ones on top. You open last month's export and it has four hundred thousand rows. Excel takes a long time to open it, the filter menu freezes, and you still have to sort and copy the result into a clean sheet. There's a calmer way to do this. The orders don't have to live in a spreadsheet at all. They can sit in a database, and you can ask it a question in a short, readable language called SQL. SQL usually answers in a moment, and it gives the same answer every time you run it. In this lesson you'll write that exact query yourself.
What you will learn. By the end of this lesson you'll be able to do three things. First, you'll use SELECT to choose which columns appear in your answer. It works like hiding the columns you don't need in Excel. Second, you'll use WHERE to keep only the rows that match a rule, just like the filter arrows on a header row. Third, you'll use ORDER BY to sort the result, the same job as the Sort button. Those three words cover a large share of the everyday questions analysts ask. You already know the ideas from Excel. Here you're only learning new names for them.
Meet SQLite. A few words first. A database is a place where tables are stored together. A table is like one Excel sheet, except every column has a fixed name and every row follows the same layout. A query is a question you write in SQL, and the database answers it with a table of rows. In this course we use SQLite. It's free and it's tiny. The whole database is a single file on your computer, so there's no server to set up and no one from IT to ask. It's also built into Python, into phones, and into many apps you already use.
The orders table. Here's the table we'll query today. It's called orders, and each row is one order placed in the online shop. The id column is the order number. Order date is the day the customer paid. Customer is the buyer's first name. Amount is the order total in dollars. Status says where the order is now: shipped, pending, or cancelled. The real shop has hundreds of thousands of rows, but we'll use just eight, shown here, so you can check every answer by eye. Keep this picture in mind. Every query we write only reads from this table. It never changes the data.
SELECT picks columns. Here's your first query. It says: select customer and amount from orders. FROM tells SQLite which table to read. SELECT lists the columns you want back, separated by commas, and they come out in the order you wrote them. The semicolon at the end marks where the query stops. If you want every column, write SELECT, then a star, then FROM orders. The star means all columns. That's handy for a quick look, but naming the columns keeps your result tidy. SQL also doesn't care about capital letters in its keywords. Writing them in capitals is simply a habit that makes queries easier to read.
WHERE filters rows. Now let's keep only some of the rows. It works like the filter arrow in Excel. WHERE comes after FROM and states a rule. Only rows where the rule is true come back. Here the rule is status equals shipped, so pending and cancelled orders drop out. Notice the single quotes around shipped. That's how SQL knows it's a piece of text and not a column name. For numbers you don't need quotes. You can write amount greater than fifty, or amount less than or equal to twenty. And you can stack rules. Status equals shipped AND amount greater than fifty needs both rules to be true, while OR only needs one of them.
ORDER BY sorts the result. The last piece is sorting. ORDER BY names the column to sort on. By default SQL sorts in ascending order, which means smallest first, or A to Z for text. Add the word DESC, short for descending, and the order flips so the largest amount comes first. You can also sort on more than one column. For example, ORDER BY customer, then a comma, then amount DESC groups each customer's orders together, with their biggest order on top. One more thing to know: without ORDER BY, SQL promises no order at all. If order matters to your report, always ask for it.
Worked example: all three together. Let's answer the manager's question. Here are the eight orders. Now we type the full query: select id, customer and amount from orders, where status equals shipped, order by amount descending. Watch the order in which SQLite actually works, because it's not the order we wrote it in. First it reads the table named in FROM. Then WHERE runs, and only shipped orders survive, so Ben's and Dina's go away. Next SELECT runs, and we keep three columns. Last, ORDER BY puts the biggest amount on top. And five rows come back, with Omar's two hundred and ten dollar order leading the list.
Try it from Python. You don't need Python for SQL, but if you have it, SQLite is already built in, so this is a quick way to practise. The first lines create an in-memory database, which is a database that lives only while the script runs. Then we make the orders table and load our eight rows into it. The query in the middle is pure SQL. This time we ask for every order over fifty dollars, whatever its status, largest first. Can you predict the result before looking? Pause the video and try. Here's the answer: Omar, Ben, Sara, Dina, then Ana at sixty. Pending and cancelled orders are included here because this time we didn't filter on status.
Common mistake: text without quotes. Here's the mistake almost everyone makes in their first week. You write where status equals shipped and leave out the quotes. SQLite reads the bare word shipped as the name of a column, can't find one, and stops with the error "no such column: shipped". The fix is to put single quotes around any text value, like shipped, Cairo, or a date such as twenty twenty-six, zero one, zero three. Numbers never need quotes. A second, related habit is to watch the spelling and capitals inside the quotes. For text comparisons, Shipped with a capital S isn't the same as lowercase shipped, so match the data exactly.
Recap. Let's wrap up. SELECT chooses which columns you see, and FROM tells SQLite which table to read. WHERE keeps only the rows that match your rule. Text goes in single quotes, and you can combine rules with AND and OR. ORDER BY sorts the result. Ascending is the default, and DESC puts the largest values first. You write the keywords in the order SELECT, FROM, WHERE, ORDER BY, even though SQLite filters before it picks columns. With just these three words you can already answer a lot of the questions that used to take you a filter, a sort, and a copy and paste in Excel.
Your exercise. Now it's your turn. Using the same eight-row orders table, write one query that shows the order date, customer and amount for pending orders only, with the newest order first. Here's a hint: dates written as year, month, day sort correctly as text, so ORDER BY order date with DESC works. You can run it in the Python script from this lesson or in any SQLite tool. When it works, you should get two rows, with Ben's order from the eighth of January on top. In the next lesson we'll summarise orders the way a pivot table does, with GROUP BY.
استكشف الرسوم المتحركة
الرسوم المتحركة نفسها التي في الفيديو، دقيقة وتفاعلية: شغّلها أو أوقفها، أو اسحب المؤشر، أو انتقل إلى أي خطوة بالسرعة التي تناسبك.
Loading the animation...
Loading the animation...
تعمل لغة Python داخل متصفحك دون أي تثبيت. في أول تشغيل يُنزَّل Python (نحو 20 ميجابايت، ثم يُحفظ في المتصفح).
1 Pending orders, newest first
The eight-row orders table is already loaded. Change query so that it shows order_date, customer and amount for pending orders only, with the newest order first. The result should have two rows, with Ben's order from 2026-01-08 on top.
2 Big shipped orders
Complete query so it returns id, customer and amount for orders that are shipped AND over 50 dollars, largest amount first. Store the rows in result (the starter already does this).
أجب عن كل الأسئلة ثم تحقّق. تنجح بنسبة 70%، ويمكنك إعادة المحاولة كما تشاء.
ملخص الدرس
- القراءة
- مشاهدة الفيديو
- التمارين
- اجتياز الاختبار (70%)
- SELECT chooses columns, FROM names the table
- WHERE keeps rows that match a rule
- ORDER BY sorts; DESC puts the largest first