מדריך שיעורי SQL בעברית

← דף הבית
📖 מדריך שיעורים
🏠 דף הבית 🎯 תרגול מקיף 📚 חומר לימוד ✏️ תרגולים 🧠 קוויז
שיעור 1 / 4
🗄️ מבוא ל-SQL ומסדי נתונים
מה זה SQL, למה הוא נחוץ, איך נראה מסד נתונים ומה ההבדל בין SQL לאקסל.
SQL Database Primary Key Foreign Key Northwind
🔍 מה זה SQL?
הגדרה
SQL = Structured Query Language — שפת שאילתות מובנית.

בניגוד לשפות כמו Python או Java שהן "שפות למטרות כלליות", SQL היא שפה ייעודית (Domain-Specific) שנוצרה אך ורק לעבודה עם נתונים.

התחביר (Syntax) של SQL מזכיר אנגלית פשוטה — פקודות כמו SELECT, FROM, WHERE הופכות את הקוד לקריא ומובן.
📜
היסטוריה: SQL פותחה בשנות ה-70 במעבדות IBM ונקראה בתחילה SEQUEL. מאז היא נשארת השפה המובילה בעולם הנתונים — מעל 50 שנה!
❓ למה בכלל SQL ולא אקסל?
3 סיבות עיקריות
1. Big Data — נפחי מידע עצומים
כשאקסל מתחיל "לגמגם" (סביב מיליון שורות) — SQL רק מתחיל להתחמם. SQL מעבד מיליארדי שורות בשניות בודדות.

2. "האמת האחת" — מסד נתונים מרכזי
בניגוד לקבצים שמסתובבים במיילים ומשתנים, SQL שומר על בסיס נתונים מרכזי אחד, מונע טעויות ושומר על קשרים לוגיים תקינים.

3. שליפה כירורגית
אקסל טוען את כל הקובץ לזיכרון. SQL שולף רק את הנתונים הספציפיים שצריך — חוסך זיכרון ומקצר זמני ריצה.
קריטריוןאקסלSQL
כמות שורותעד ~1M שורותמיליארדי שורות
מהירותאיטי עם קבצים גדוליםמהיר מאוד
שיתוף נתוניםקבצים שמסתובביםמסד מרכזי אחד
אבטחהכל אחד יכול לערוךהרשאות ובקרה
ביצוע חישוביםנוח למשתמש רגילעוצמתי ומדויק
🗃️ איך נראה מסד נתונים?
מבנה מסד נתונים
מסד נתונים (Database) מורכב מטבלאות (Tables). כל טבלה מכילה עמודות (Columns) ושורות (Rows).

דמיינו כמה גיליונות אקסל שקשורים זה לזה — כך נראה מסד נתונים.
1
Database — מסד הנתונים הכולל (למשל: Northwind)
2
Tables — טבלאות בתוך מסד הנתונים (למשל: customers, orders, products)
3
Columns — עמודות בטבלה (למשל: id, first_name, city)
4
Rows — שורות נתונים (למשל: פרטי לקוח ספציפי)
🔑 מפתחות וקשרים
Primary Key — מפתח ראשי
עמודה שמזהה כל שורה באופן ייחודי. לא יכולים להיות שני ערכים זהים. לא יכול להיות NULL.
דוגמה: עמודת id בטבלת לקוחות — לכל לקוח יש מספר ייחודי משלו.
Foreign Key — מפתח זר
עמודה בטבלה אחת שמפנה לPrimary Key בטבלה אחרת. יוצרת את הקשר בין הטבלאות.
דוגמה: עמודת customer_id בטבלת orders מפנה ל-id בטבלת customers.
💡
טיפ: הקשר בין מפתח ראשי למשני הוא הבסיס לפקודת JOIN — זה איך מחברים מידע מטבלאות שונות.
🏪 מסד הנתונים של הקורס — Northwind
מה זה Northwind?
מסד נתונים קלאסי שמדמה חברת מסחר. כולל לקוחות, הזמנות, מוצרים, ספקים ועובדים. בשימוש נרחב ללימוד SQL כבר עשרות שנים.
הטבלאות הראשיות
customers — לקוחות | orders — הזמנות | order_details — פרטי הזמנות
products — מוצרים | employees — עובדים | suppliers — ספקים | shippers — חברות שילוח
שיעור 2 / 4
📝 פונקציות מחרוזת (String Functions)
ניקוי, חילוץ, עיצוב ותקינה של נתוני טקסט. 4 קטגוריות פעולה עיקריות.
UPPER / LOWER LEFT / RIGHT SUBSTRING TRIM / REPLACE LENGTH CONCAT
🧹 קטגוריה 1: ניקוי נתונים (Cleaning)
TRIM / LTRIM / RTRIM
מסיר רווחים מיותרים מהמחרוזת.
TRIM — משני הצדדים | LTRIM — משמאל בלבד | RTRIM — מימין בלבד
SQL
SELECT TRIM('   שלום עולם   ') AS clean_text;
-- תוצאה: 'שלום עולם'

SELECT company, TRIM(company) AS clean_company
FROM customers;
REPLACE
מחליף תת-מחרוזת אחת באחרת.
REPLACE(עמודה, 'מה להחליף', 'במה')
SQL
-- הסרת מקפים ממספרי טלפון
SELECT REPLACE(business_phone, '-', '') AS clean_phone
FROM customers;

-- החלפת UK ב-United Kingdom
SELECT REPLACE(country_region, 'UK', 'United Kingdom')
FROM customers;
✂️ קטגוריה 2: חילוץ נתונים (Extraction)
LEFT / RIGHT
LEFT(עמודה, N) — N תווים מהתחלה
RIGHT(עמודה, N) — N תווים מהסוף
SQL
-- 3 אותיות ראשונות משם החברה
SELECT company, LEFT(company, 3) AS short_code
FROM customers;

-- 4 ספרות אחרונות של טלפון
SELECT RIGHT(business_phone, 4) AS phone_end
FROM customers;
SUBSTRING
SUBSTRING(עמודה, התחלה, אורך) — חילוץ ממיקום ספציפי.
חשוב: המיקום מתחיל מ-1 (לא מ-0!).
SQL
-- 5 תווים החל מהתו ה-2
SELECT SUBSTRING(product_name, 2, 5) AS middle_text
FROM products;
LENGTH ו-INSTR
LENGTH(עמודה) — מחזיר את אורך המחרוזת במספר תווים
INSTR(עמודה, 'תו') — מחזיר את המיקום של תת-מחרוזת
SQL
SELECT email_address,
       LENGTH(email_address) AS email_length,
       INSTR(email_address, '@') AS at_position
FROM employees;
🎨 קטגוריה 3: עיצוב מחדש (Formatting)
CONCAT ו-CONCAT_WS
CONCAT(a, b, c) — מחבר מחרוזות. אם אחד מהערכים הוא NULL — התוצאה NULL.
CONCAT_WS(מפריד, a, b, c) — מחבר עם מפריד קבוע ומדלג על NULL אוטומטית.
SQL
-- כתובת מלאה עם פסיקים (מדלג על NULL)
SELECT CONCAT_WS(', ', city, state_province, zip_postal_code) AS full_address
FROM customers;

-- מחיר עם סימן $
SELECT CONCAT('$', ROUND(list_price, 2)) AS formatted_price
FROM products;
✅ קטגוריה 4: תקינה ואחידות (Standardization)
UPPER / LOWER
UPPER(עמודה) — הופך את כל הטקסט לאותיות גדולות
LOWER(עמודה) — הופך את כל הטקסט לאותיות קטנות

שימושי לנורמליזציה של נתונים לפני השוואה.
SQL
SELECT UPPER(company) AS company_caps
FROM suppliers;

SELECT LOWER(email_address) AS standard_email
FROM employees;
⚠️
שים לב: UPPER/LOWER משנים את התצוגה בלבד — הם לא שומרים את השינוי בטבלה. לשינוי קבוע צריך UPDATE.
שיעור 3 / 4
🔎 WHERE — סינון נתונים
סינון שורות לפי תנאים. הכלי הכי חיוני לשאילתות אמיתיות — כולל AND/OR, IN, BETWEEN, LIKE ו-IS NULL.
WHERE AND / OR IN BETWEEN LIKE IS NULL
📍 WHERE בסיסי
תחביר
WHERE מגיע אחרי FROM ומסנן שורות לפי תנאי.
אופרטורי השוואה: = != < > <= >=
SQL
-- מוצרים שמחירם מעל 50
SELECT product_name, list_price
FROM products
WHERE list_price > 50;

-- עובדים שאינם Sales Representative
SELECT first_name, job_title
FROM employees
WHERE job_title != 'Sales Representative';
🔗 AND / OR — תנאים מרובים
ההבדל
ANDשני התנאים חייבים להתקיים
ORלפחות אחד מהתנאים צריך להתקיים

סוגריים קובעים עדיפות: WHERE (a OR b) AND c
SQL
-- AND: לקוחות מ-USA ומ-New York
SELECT * FROM customers
WHERE country_region = 'USA'
  AND city = 'New York';

-- OR: מוצרים מ-Beverages או Condiments
SELECT product_name FROM products
WHERE category = 'Beverages'
   OR category = 'Condiments';
📋 IN — רשימת ערכים
מה זה IN?
IN הוא קיצור נוח ל-OR מרובה. קריא יותר וקצר יותר.
WHERE city IN ('Tel Aviv', 'Jerusalem', 'Haifa')
SQL
-- ספקים מ-3 ערים (קיצור ל-OR)
SELECT company, city
FROM suppliers
WHERE city IN ('Tokyo', 'London', 'New York');

-- NOT IN: לא מהערים האלה
SELECT * FROM customers
WHERE country_region NOT IN ('USA', 'UK');
📏 BETWEEN — טווח ערכים
חשוב לדעת
BETWEEN x AND y — כולל את שני הקצוות (x ו-y עצמם).
שקול ל: WHERE col >= x AND col <= y
SQL
-- הזמנות עם דמי משלוח בין 20 ל-50
SELECT id, shipping_fee
FROM orders
WHERE shipping_fee BETWEEN 20 AND 50;
🔍 LIKE — חיפוש דפוס
תווי wildcard
% — כל מספר תווים (גם אפס)
_ — תו בודד בדיוק

'%gmail%' — מכיל gmail | 'j%' — מתחיל ב-j | '%@gmail.com' — מסתיים ב-@gmail.com
SQL
-- אימיילים שמסתיימים ב-northwindtraders.com
SELECT * FROM employees
WHERE email_address LIKE '%northwindtraders.com';

-- שמות שמתחילים ב-A
SELECT first_name FROM employees
WHERE first_name LIKE 'A%';
🚫 IS NULL / IS NOT NULL
NULL — ערך חסר
NULL הוא ערך חסר / לא ידוע — לא אפס, לא ריק!
לא ניתן להשתמש ב-= NULL — חייבים IS NULL.
SQL
-- הזמנות שטרם נשלחו
SELECT id, order_date
FROM orders
WHERE shipped_date IS NULL;

-- לקוחות עם אתר אינטרנט
SELECT company, web_page
FROM customers
WHERE web_page IS NOT NULL;
שגיאה נפוצה! WHERE shipped_date = NULL — זה לא עובד ב-SQL! תמיד משתמשים ב-IS NULL.
שיעור 4 / 4
📦 GROUP BY וצבירה
קיבוץ שורות וחישוב סטטיסטיקות — COUNT, SUM, AVG, MIN, MAX. כולל HAVING, ROLLUP ו-UNION.
GROUP BY COUNT SUM / AVG MIN / MAX HAVING ROLLUP UNION
📊 פונקציות צבירה
הפונקציות העיקריות
COUNT(*) — סופר שורות | COUNT(עמודה) — סופר ערכים לא-NULL
SUM(עמודה) — מחשב סכום
AVG(עמודה) — מחשב ממוצע
MIN(עמודה) — הערך הנמוך ביותר
MAX(עמודה) — הערך הגבוה ביותר
SQL
-- סטטיסטיקות על טבלת המוצרים
SELECT
  COUNT(*) AS total_products,
  AVG(list_price) AS avg_price,
  MIN(list_price) AS min_price,
  MAX(list_price) AS max_price
FROM products;
🗂️ GROUP BY — קיבוץ לפי קבוצות
הכלל החשוב
כל עמודה ב-SELECT שאינה פונקציית צבירה חייבת להיות ב-GROUP BY.
GROUP BY מחלק את הטבלה לקבוצות ומחשב צבירה לכל קבוצה.
SQL
-- כמה מוצרים יש בכל קטגוריה?
SELECT category, COUNT(*) AS product_count
FROM products
GROUP BY category;

-- ממוצע מחיר לקטגוריה
SELECT category, AVG(list_price) AS avg_price
FROM products
GROUP BY category
ORDER BY avg_price DESC;
🔍 HAVING — סינון אחרי קיבוץ
WHERE לעומת HAVING
WHERE — מסנן שורות לפני הקיבוץ
HAVING — מסנן קבוצות אחרי הקיבוץ

כלל: לא ניתן להשתמש בפונקציות צבירה (COUNT, SUM…) ב-WHERE. לכן צריך HAVING.
SQL
-- קטגוריות עם יותר מ-5 מוצרים
SELECT category, COUNT(*) AS cnt
FROM products
GROUP BY category
HAVING COUNT(*) > 5;

-- WHERE (לפני) + HAVING (אחרי)
SELECT category, AVG(list_price) AS avg
FROM products
WHERE list_price > 10        -- סינון לפני קיבוץ
GROUP BY category
HAVING AVG(list_price) > 30; -- סינון אחרי קיבוץ
💡
טריק לזכור: WHERE → לפני GROUP BY (על שורות). HAVING → אחרי GROUP BY (על קבוצות).
📈 ROLLUP — סיכום כולל
מה זה ROLLUP?
GROUP BY עמודה WITH ROLLUP — מוסיף שורת סיכום כולל בסוף התוצאות.
השורה האחרונה תכיל NULL בעמודת הקיבוץ וסה"כ כולל.
SQL
-- ספירה לפי קטגוריה + סה"כ
SELECT
  COALESCE(category, '--- סה"כ ---') AS category,
  COUNT(*) AS total
FROM products
GROUP BY category WITH ROLLUP;
🔀 UNION — איחוד תוצאות
UNION לעומת UNION ALL
UNION — מאחד תוצאות של שתי שאילתות ומסיר כפילויות
UNION ALL — מאחד ושומר כפילויות (מהיר יותר)

תנאי: שתי השאילתות חייבות להחזיר אותו מספר עמודות עם סוגי נתונים תואמים.
SQL
-- רשימה מאוחדת של ערים מלקוחות ומספקים
SELECT city, 'לקוח' AS type FROM customers
UNION
SELECT city, 'ספק' AS type FROM suppliers
ORDER BY city;
📋 סדר ביצוע SQL — חשוב לדעת!
1
FROM — מאיזו טבלה לשלוף
2
WHERE — סינון שורות
3
GROUP BY — קיבוץ לקבוצות
4
HAVING — סינון קבוצות
5
SELECT — בחירת עמודות לתצוגה
6
ORDER BY — מיון התוצאות
7
LIMIT — הגבלת כמות שורות
💡
הסדר שאנחנו כותבים SQL שונה מהסדר שה-DB מבצע אותו. זו הסיבה שלא ניתן להשתמש ב-Alias מ-SELECT בתוך WHERE.