Mission Carthage

الرئيسية › الدروس › SQL: الربط، التجميع والاستعلامات الفرعية

SQL: الربط بين الجداول وGROUP BY وHAVING والاستعلامات الفرعية

الفصل 29 · باك علوم الإعلامية

اربط برشا tables في requête وحدة، احسب وجمّع حسب المجموعات بـ GROUP BY و HAVING، استعمل requête داخل أخرى، واحسب بالتواريخ.

دروس هذا الفصل

  1. الربط بين الـ tables (jointures)
  2. نحسبو ونجمّعو
  3. الاستعلامات الفرعية والتواريخ

الدرس 29.1 : الربط بين الـ tables (jointures)

12 دقيقة

الـ jointure تجمع الأسطر متاع زوز tables اللي يمشيو مع بعضهم: كل تلميذ مع القسم متاعو. تتكتب بـ JOIN والشرط اللي يربطهم بعد ON: الـ clé étrangère تساوي الـ clé primaire.

SELECT eleve.nom, classe.niveau, classe.salle
FROM eleve JOIN classe ON eleve.code_classe = classe.code;

انتبه : كي يكون عند زوز tables عمود بنفس الاسم، MySQL ما يعرفش أشكون ياخو: غلطة #1052 (« ambiguous »). اكتب table.colonne ولا alias.colonne.

بـ SQL

خدّم، وبعد زيد WHERE c.niveau = 'Bac SI' قبل الـ ORDER BY باش تخلّي كان تلامذة الباك.

CREATE TABLE classe (code VARCHAR(5) PRIMARY KEY, niveau VARCHAR(20) NOT NULL, salle VARCHAR(5));
CREATE TABLE eleve (
  id INT PRIMARY KEY,
  nom VARCHAR(30) NOT NULL,
  code_classe VARCHAR(5),
  moyenne DECIMAL(4,2),
  date_naissance DATE,
  FOREIGN KEY (code_classe) REFERENCES classe(code)
);
INSERT INTO classe VALUES ('4SI1', 'Bac SI', 'B12'), ('4SI2', 'Bac SI', 'B14'), ('3SI1', '3ème SI', 'A03');
INSERT INTO eleve VALUES
  (1, 'Ben Salah', '4SI1', 12.50, '2008-03-14'),
  (2, 'Trabelsi', '4SI1', 16.25, '2008-07-02'),
  (3, 'Jaziri', '4SI2', 9.75, '2008-11-23'),
  (4, 'Mansour', '4SI2', 14.00, '2007-12-30'),
  (5, 'Bouzid', '3SI1', 11.00, '2009-05-05');

SELECT e.nom, c.niveau, c.salle
FROM eleve e JOIN classe c ON e.code_classe = c.code
ORDER BY e.nom;

الدرس 29.2 : نحسبو ونجمّعو

12 دقيقة

الـ fonctions d'agrégation

SELECT COUNT(*) AS nb, AVG(moyenne) AS moy_generale, MAX(moyenne) AS meilleure FROM eleve;

GROUP BY و HAVING

GROUP BY يقسم الأسطر لـ مجموعات عندها نفس القيمة، والـ fonctions d'agrégation يحسبو نتيجة لكل مجموعة. HAVING بعد يصفّي المجموعات، كيما WHERE يصفّي الأسطر.

SELECT code_classe, COUNT(*) AS nb, AVG(moyenne) AS moy
FROM eleve
GROUP BY code_classe
HAVING COUNT(*) >= 2;

انتبه : العمود في الـ SELECT اللي موش fonction d'agrégation لازمو يكون في الـ GROUP BY. والشرط على COUNT ولا SUM يمشي في HAVING، عمرو ما يمشي في WHERE (غلطة #1111).

نصيحة : ترتيب الكتيبة ديما: SELECT … FROM … JOIN … WHERE … GROUP BY … HAVING … ORDER BY … LIMIT ….

بـ SQL

خدّم، وبعد بدّل HAVING COUNT(*) >= 2 بـ HAVING AVG(moyenne) >= 12: أنهوما الأقسام اللي يبقاو؟

CREATE TABLE classe (code VARCHAR(5) PRIMARY KEY, niveau VARCHAR(20) NOT NULL, salle VARCHAR(5));
CREATE TABLE eleve (
  id INT PRIMARY KEY,
  nom VARCHAR(30) NOT NULL,
  code_classe VARCHAR(5),
  moyenne DECIMAL(4,2),
  date_naissance DATE,
  FOREIGN KEY (code_classe) REFERENCES classe(code)
);
INSERT INTO classe VALUES ('4SI1', 'Bac SI', 'B12'), ('4SI2', 'Bac SI', 'B14'), ('3SI1', '3ème SI', 'A03');
INSERT INTO eleve VALUES
  (1, 'Ben Salah', '4SI1', 12.50, '2008-03-14'),
  (2, 'Trabelsi', '4SI1', 16.25, '2008-07-02'),
  (3, 'Jaziri', '4SI2', 9.75, '2008-11-23'),
  (4, 'Mansour', '4SI2', 14.00, '2007-12-30'),
  (5, 'Bouzid', '3SI1', 11.00, '2009-05-05');

SELECT code_classe, COUNT(*) AS nb, AVG(moyenne) AS moy
FROM eleve
GROUP BY code_classe
HAVING COUNT(*) >= 2;

الدرس 29.3 : الاستعلامات الفرعية والتواريخ

12 دقيقة

requête داخل requête

الـ sous-requête هي SELECT بين أقواس، محطوطة في الـ WHERE متاع requête أخرى. تتحسب الأوّل، ومن بعد النتيجة متاعها تخدم في الشرط.

SELECT nom, moyenne FROM eleve
WHERE moyenne > (SELECT AVG(moyenne) FROM eleve);

SELECT nom FROM eleve
WHERE code_classe IN (SELECT code FROM classe WHERE niveau = 'Bac SI');

نحسبو بالتواريخ

SELECT nom, YEAR(date_naissance) AS annee FROM eleve WHERE MONTH(date_naissance) >= 7;

بـ SQL

خدّم: الـ requête الأولى تخلّي التلامذة اللي فوق المعدّل العام. زيد requête تورّي اسم كل تلميذ والعمر متاعو بالأيام في 1 أكتوبر 2026 بـ DATEDIFF('2026-10-01', date_naissance).

CREATE TABLE classe (code VARCHAR(5) PRIMARY KEY, niveau VARCHAR(20) NOT NULL, salle VARCHAR(5));
CREATE TABLE eleve (
  id INT PRIMARY KEY,
  nom VARCHAR(30) NOT NULL,
  code_classe VARCHAR(5),
  moyenne DECIMAL(4,2),
  date_naissance DATE,
  FOREIGN KEY (code_classe) REFERENCES classe(code)
);
INSERT INTO classe VALUES ('4SI1', 'Bac SI', 'B12'), ('4SI2', 'Bac SI', 'B14'), ('3SI1', '3ème SI', 'A03');
INSERT INTO eleve VALUES
  (1, 'Ben Salah', '4SI1', 12.50, '2008-03-14'),
  (2, 'Trabelsi', '4SI1', 16.25, '2008-07-02'),
  (3, 'Jaziri', '4SI2', 9.75, '2008-11-23'),
  (4, 'Mansour', '4SI2', 14.00, '2007-12-30'),
  (5, 'Bouzid', '3SI1', 11.00, '2009-05-05');

SELECT nom, moyenne FROM eleve
WHERE moyenne > (SELECT AVG(moyenne) FROM eleve);
SELECT nom FROM eleve
WHERE code_classe IN (SELECT code FROM classe WHERE niveau = 'Bac SI');

تدرّب مجانًا

كل درس فيه 3 تمارين مجانية مع تلميحات باش تطبّق الفصل هذا مع هنّيبوت.

افتح الفصل في Mission Carthage جرّب في الكومبيلاتور أونلاين

← الفصل اللي قبل : استعلامات SQL بسيطة · الفصل اللي بعد : PHP: أوّل السكريبتات →

كل الفصول · شوف فروض 2 تكنولوجيا المصلّحة

الدروس كتبناها لـ Mission Carthage على أساس البرنامج الرسمي. الأستاذ متاعك يبقى المرجع.