SQL. Probleme interesante

Bună, Habr!

De mai bine de 3 ani, predau SQL în diferite centre de formare, iar una dintre observațiile mele este că studenții învață și înțeleg SQL mai bine atunci când li se pune o sarcină, în loc să li se vorbească doar despre posibilități și fundamente teoretice.

În acest articol, voi împărtăși cu voi lista mea de sarcini pe care le dau studenților ca temă de lucru și asupra cărora organizăm diverse sesiuni de brainstorming, ceea ce duce la o înțelegere profundă și clară a SQL.

SQL. Probleme interesante

SQL (ˈɛsˈkjuˈɛl; engl. structured query language — „limbaj de interogare structurat”) este un limbaj de programare declarativ, utilizat pentru crearea, modificarea și gestionarea datelor într-o bază de date relațională, administrată de un sistem de gestionare a bazelor de date corespunzător. Mai multe informații…

Puteți citi despre SQL din diferite surse. surse.
Acest articol nu are ca scop să vă învețe SQL de la zero.

Așadar, să începem.

Vom folosi binecunoscutul schema HR în Oracle cu tabelele sale (Află mai multe):

SQL. Probleme interesante
Menționez că vom analiza doar sarcinile pe SELECT. Nu sunt incluse sarcini pe DML și DDL.

Sarcini

Restricționarea și sortarea datelor

Tabelul Employees. Obțineți o listă cu informații despre toți angajații
Soluție

SELECT * FROM employees

Tabelul Employees. Obțineți o listă cu toți angajații cu numele ‘David’
Soluție

SELECT *
  FROM employees
 WHERE first_name = 'David';

Tabelul Employees. Obțineți o listă cu toți angajații cu job_id egal cu ‘IT_PROG’
Soluție

SELECT *
  FROM employees
 WHERE job_id = 'IT_PROG'

Tabelul Employees. Obțineți o listă cu toți angajații din departamentul 50 (department_id) cu salariul (salary) mai mare de 4000
Soluție

SELECT *
  FROM employees
 WHERE department_id = 50 AND salary > 4000;

Tabelul Employees. Obțineți o listă cu toți angajații din departamentele 20 și 30 (department_id)
Soluție

SELECT *
  FROM employees
 WHERE department_id = 20 OR department_id = 30;

Tabelul Employees. Obțineți o listă cu toți angajații ale căror nume se termină cu litera ‘a’
Soluție

SELECT *
  FROM employees
 WHERE first_name LIKE '%a';

Tabelul Employees. Obțineți o listă cu toți angajații din departamentele 50 și 80 (department_id) care au bonus (valoarea din coloana commission_pct nu este goală)
Soluție

SELECT *
  FROM employees
 WHERE     (department_id = 50 OR department_id = 80)
       AND commission_pct IS NOT NULL;

Tabelul Employees. Obțineți o listă cu toți angajații ale căror nume conțin cel puțin 2 litere ‘n’
Soluție

SELECT *
  FROM employees
 WHERE first_name LIKE '%n%n%';

Tabelul Employees. Obțineți o listă cu toți angajații ale căror nume au mai mult de 4 litere
Soluție

SELECT *
  FROM employees
 WHERE first_name LIKE '%_____%';

Tabelul Employees. Obțineți o listă cu toți angajații ale căror salarii se află între 8000 și 9000 (inclusiv)
Soluție

SELECT *
  FROM employees
 WHERE salary BETWEEN 8000 AND 9000;

Tabela Employees. Obține lista tuturor angajaților care au simbolul '%' în nume
Soluție

SELECT *
  FROM employees
 WHERE first_name LIKE '%%%' ESCAPE '';

Tabela Employees. Obține lista tuturor ID-urilor managerilor
Soluție

SELECT DISTINCT manager_id
  FROM employees
 WHERE manager_id IS NOT NULL;

Tabela Employees. Obține lista angajaților cu pozițiile lor în formatul: Donald(sh_clerk)
Soluție

SELECT first_name || '(' || LOWER (job_id) || ')' employee FROM employees;

Folosind funcții cu un singur rând pentru a personaliza ieșirea

Tabela Employees. Obține lista tuturor angajaților a căror lungime a numelui depășește 10 litere
Soluție

SELECT *
  FROM employees
 WHERE LENGTH (first_name) > 10;

Tabela Employees. Obține lista tuturor angajaților care au litera 'b' în nume (fără a lua în considerare majusculele și minusculele)
Soluție

SELECT *
  FROM employees
 WHERE INSTR (LOWER (first_name), 'b') > 0;

Tabela Employees. Obține lista tuturor angajaților care au în nume cel puțin două litere 'a'
Soluție

SELECT *
  FROM employees
 WHERE INSTR (LOWER (first_name),'a',1,2) > 0;

Tabela Employees. Obține lista tuturor angajaților ale căror salarii sunt multipli de 1000
Soluție

SELECT *
  FROM employees
 WHERE MOD (salary, 1000) = 0;

Tabela Employees. Obține primul număr de 3 cifre din numărul de telefon al angajatului, dacă numărul său este în formatul XXX.XXX.XXXX
Soluție

SELECT phone_number, SUBSTR (phone_number, 1, 3) new_phone_number
  FROM employees
 WHERE phone_number LIKE '___.___.____';

Tabela Departments. Obține primul cuvânt din numele departamentului pentru cei care au mai multe cuvinte în denumire
Soluție

SELECT department_name,
       SUBSTR (department_name, 1, INSTR (department_name, ' ')-1)
           first_word
  FROM departments
 WHERE INSTR (department_name, ' ') > 0;

Tabela Employees. Obține numele angajaților fără prima și ultima literă din nume
Soluție

SELECT first_name, SUBSTR (first_name, 2, LENGTH (first_name) - 2) new_name
  FROM employees;

Tabela Employees. Obține lista tuturor angajaților a căror ultimă literă din nume este 'm' și lungimea numelui este mai mare de 5
Soluție

SELECT *
  FROM employees
 WHERE SUBSTR (first_name, -1) = 'm' AND LENGTH(first_name) > 5;

Tabela Dual. Obține data următoarei zile de vineri
Soluție

SELECT NEXT_DAY (SYSDATE, 'FRIDAY') next_friday FROM DUAL;

Tabela Employees. Obține lista tuturor angajaților care lucrează în companie de mai bine de 17 ani
Soluție

SELECT *
  FROM employees
 WHERE MONTHS_BETWEEN (SYSDATE, hire_date) / 12 > 17;

Tabela Employees. Obține lista tuturor angajaților ale căror ultime cifre ale numărului de telefon sunt impari și constau din 3 cifre separate prin punct
Soluție

SELECT *
  FROM employees
 WHERE MOD (SUBSTR (phone_number, -1), 2) != 0
       AND INSTR (phone_number,'.',1,3) = 0;

Tabela Employees. Obține lista tuturor angajaților a căror valoare job_id după semnul '_' are cel puțin 3 caractere, dar acestă valoare după '_' nu este 'CLERK'
Soluție

SELECT *
  FROM employees
 WHERE     LENGTH (SUBSTR (job_id, INSTR (job_id, '_') + 1)) > 3
       AND SUBSTR (job_id, INSTR (job_id, '_') + 1) != 'CLERK';

Tabelă Employees. Obțineți lista tuturor angajaților înlocuind în valoarea PHONE_NUMBER toate ‘.’ cu ‘-‘
Soluție

SELECT phone_number, REPLACE (phone_number, '.', '-') new_phone_number
  FROM employees;

Folosind funcții de conversie și expresii condiționale

Tabelă Employees. Obțineți lista tuturor angajaților care au început munca în prima zi a oricărei luni
Soluție

SELECT *
  FROM employees
 WHERE TO_CHAR (hire_date, 'DD') = '01';

Tabelă Employees. Obțineți lista tuturor angajaților care au început munca în anul 2008
Soluție

SELECT *
  FROM employees
 WHERE TO_CHAR (hire_date, 'YYYY') = '2008';

Tabelă DUAL. Afișați data de mâine în format: Mâine este a doua zi din ianuarie
Soluție

SELECT TO_CHAR (SYSDATE, 'fm""Mâine este ""Ddspth ""ziua din"" Lunar')     info
  FROM DUAL;

Tabelă Employees. Obțineți lista tuturor angajaților și data începerii muncii fiecăruia în format: 21st of June, 2007
Soluție

SELECT first_name, TO_CHAR (hire_date, 'fmddth ""din"" Lunar, YYYY') hire_date
  FROM employees;

Tabelă Employees. Obțineți lista angajaților cu salarii mărite cu 20%. Salariul să fie afișat cu semnul dolarului
Soluție

SELECT first_name, TO_CHAR (salary + salary * 0.20, 'fm$999,999.00') new_salary
  FROM employees;

Tabelă Employees. Obțineți lista tuturor angajaților care au început munca în februarie 2007.
Soluție

SELECT *
  FROM employees
 WHERE hire_date BETWEEN TO_DATE ('01.02.2007', 'DD.MM.YYYY')
                     AND LAST_DAY (TO_DATE ('01.02.2007', 'DD.MM.YYYY'));

SELECT *
  FROM employees
 WHERE to_char(hire_date,'MM.YYYY') = '02.2007'; 

Tabelă DUAL. Afișați data curentă, + secundă, + minut, + oră, + zi, + lună, + an
Soluție

SELECT SYSDATE                          now,
       SYSDATE + 1 / (24 * 60 * 60)     plus_second,
       SYSDATE + 1 / (24 * 60)          plus_minute,
       SYSDATE + 1 / 24                 plus_hour,
       SYSDATE + 1                      plus_day,
       ADD_MONTHS (SYSDATE, 1)          plus_month,
       ADD_MONTHS (SYSDATE, 12)         plus_year
  FROM DUAL;

Tabelă Employees. Obțineți lista tuturor angajaților cu salariile complete (salary + commission_pct(%)) în format: $24,000.00
Soluție

SELECT first_name, salary, TO_CHAR (salary + salary * NVL (commission_pct, 0), 'fm$99,999.00') full_salary
  FROM employees;

Tabelă Employees. Obțineți lista tuturor angajaților și informațiile despre bonusurile la salariu (Yes/No)
Soluție

SELECT first_name, commission_pct, NVL2 (commission_pct, 'Yes', 'No') has_bonus
  FROM employees;

Tabelă Employees. Obțineți nivelul salarial al fiecărui angajat: Mai puțin de 5000 este considerat nivel scăzut, 5000 sau mai mult și mai puțin de 10000 este considerat nivel normal, 10000 sau mai mult este considerat nivel ridicat
Soluție

SELECT first_name,
       salary,
       CASE
           WHEN salary = 5000 AND salary < 10000 THEN 'Normal'
           ELSE 'High'
       END salary_level
  FROM employees;

Tabelă Countries. Pentru fiecare țară arătați regiunea în care se află: 1-Europe, 2-America, 3-Asia, 4-Africa (fără Join)
Soluție

SELECT country_name country,
       DECODE (region_id,
               1, 'Europa',
               2, 'America',
               3, 'Asia',
               4, 'Africa',
               'Necunoscut')
           region
  FROM countries;

SELECT country_name
           country,
       CASE region_id
           WHEN 1 THEN 'Europa'
           WHEN 2 THEN 'America'
           WHEN 3 THEN 'Asia'
           WHEN 4 THEN 'Africa'
           ELSE 'Necunoscut'
       END
           region
  FROM countries;

Raportarea datelor agregate folosind funcțiile de grup

Tabelul Employees. Obțineți un raport pe department_id cu salariul minim și maxim, cu data de angajare timpurie și târzie și cu numărul de angajați. Să fie sortat după numărul de angajați (în ordine descrescătoare)
Soluție

  SELECT department_id,
         MIN (salary) min_salary,
         MAX (salary) max_salary,
         MIN (hire_date) min_hire_date,
         MAX (hire_date) max_hire_date,
         COUNT (*) count
    FROM employees
GROUP BY department_id
order by count(*) desc;

Tabelul Employees. Câți angajați au numele care începe cu aceeași literă? Să fie sortat după număr. Să fie afișate doar cele unde numărul este mai mare de 1
Soluție

SELECT SUBSTR (first_name, 1, 1) first_char, COUNT (*)
    FROM employees
GROUP BY SUBSTR (first_name, 1, 1)
  HAVING COUNT (*) > 1
ORDER BY 2 DESC;

Tabelul Employees. Câți angajați lucrează în același departament și au salarii identice?
Soluție

SELECT department_id, salary, COUNT (*)
    FROM employees
GROUP BY department_id, salary
  HAVING COUNT (*) > 1;

Tabelul Employees. Obțineți un raport cu câți angajați au fost angajați în fiecare zi a săptămânii. Să fie sortat după număr
Soluție

SELECT TO_CHAR (hire_date, 'Day') day, COUNT (*)
    FROM employees
GROUP BY TO_CHAR (hire_date, 'Day')
ORDER BY 2 DESC;

Tabelul Employees. Obțineți un raport cu câți angajați au fost angajați de-a lungul anilor. Să fie sortat după număr
Soluție

SELECT TO_CHAR (hire_date, 'YYYY') year, COUNT (*)
    FROM employees
GROUP BY TO_CHAR (hire_date, 'YYYY');

Tabelul Employees. Obțineți numărul de departamente în care există angajați
Soluție

SELECT COUNT (COUNT (*)) department_count
    FROM employees
   WHERE department_id IS NOT NULL
GROUP BY department_id;

Tabelul Employees. Obțineți lista department_id unde lucrează mai mult de 30 de angajați
Soluție

  SELECT department_id
    FROM employees
GROUP BY department_id
  HAVING COUNT (*) > 30;

Tabelul Employees. Obțineți lista department_id și salariul mediu rotunjit al angajaților din fiecare departament.
Soluție

  SELECT department_id, ROUND (AVG (salary)) avg_salary
    FROM employees
GROUP BY department_id;

Tabelul Countries. Obțineți lista region_id suma tuturor literelor din toate country_name unde este mai mare de 60
Soluție

  SELECT region_id
    FROM countries
GROUP BY region_id
  HAVING SUM (LENGTH (country_name)) > 60;

Tabelul Employees. Obțineți lista department_id în care lucrează angajați cu mai multe job_id-uri (>1)
Soluție

  SELECT department_id
    FROM employees
GROUP BY department_id
  HAVING COUNT (DISTINCT job_id) > 1;

Tabelul Employees. Obține lista manager_id-urilor care au mai mult de 5 subordonați și suma tuturor salariilor subordonaților săi depășește 50000
Soluție

  SELECT manager_id
    FROM employees
GROUP BY manager_id
  HAVING COUNT (*) > 5 AND SUM (salary) > 50000;

Tabelul Employees. Obține lista manager_id-urilor ale căror salarii medii ale tuturor subordonaților se află între 6000 și 9000 și care nu primesc bonusuri (commission_pct este null)
Soluție

  SELECT manager_id, AVG (salary) avg_salary
    FROM employees
   WHERE commission_pct IS NULL
GROUP BY manager_id
  HAVING AVG (salary) BETWEEN 6000 AND 9000;

Tabelul Employees. Obține salariul maxim dintre toți angajații cu job_id care se termină cu cuvântul ‘CLERK’
Soluție

SELECT MAX (salary) max_salary
  FROM employees
 WHERE job_id LIKE '%CLERK';

SELECT MAX (salary) max_salary
  FROM employees
 WHERE SUBSTR (job_id, -5) = 'CLERK';

Tabelul Employees. Obține salariul maxim dintre toate salariile medii pe departamente
Soluție

  SELECT MAX (AVG (salary))
    FROM employees
GROUP BY department_id;

Tabelul Employees. Obține numărul angajaților cu același număr de litere în nume. Arată doar cei cu lungimea numelui mai mare de 5 și numărul angajaților cu acest nume mai mare de 20. Sortează după lungimea numelui
Soluție

  SELECT LENGTH (first_name), COUNT (*)
    FROM employees
GROUP BY LENGTH (first_name)
  HAVING LENGTH (first_name) > 5 AND COUNT (*) > 20
ORDER BY LENGTH (first_name);

  SELECT LENGTH (first_name), COUNT (*)
    FROM employees
   WHERE LENGTH (first_name) > 5
GROUP BY LENGTH (first_name)
  HAVING COUNT (*) > 20
ORDER BY LENGTH (first_name);

Afișarea datelor din mai multe tabele folosind Joins

Tabelul Employees, Departaments, Locations, Countries, Regions. Obține lista regiunilor și numărul angajaților din fiecare regiune
Soluție

  SELECT region_name, COUNT (*)
    FROM employees e
         JOIN departments d ON (e.department_id = d.department_id)
         JOIN locations l ON (d.location_id = l.location_id)
         JOIN countries c ON (l.country_id = c.country_id)
         JOIN regions r ON (c.region_id = r.region_id)
GROUP BY region_name;

Tabelul Employees, Departaments, Locations, Countries, Regions. Obține informații detaliate despre fiecare angajat:
First_name, Last_name, Departament, Job, Street, Country, Region
Soluție

SELECT First_name,
       Last_name,
       Department_name,
       Job_id,
       street_address,
       Country_name,
       Region_name
  FROM employees e
       JOIN departments d ON (e.department_id = d.department_id)
       JOIN locations l ON (d.location_id = l.location_id)
       JOIN countries c ON (l.country_id = c.country_id)
       JOIN regions r ON (c.region_id = r.region_id);

Tabelul Employees. Arată toți managerii care au în subordine mai mult de 6 angajați
Soluție

  SELECT man.first_name, COUNT (*)
    FROM employees emp JOIN employees man ON (emp.manager_id = man.employee_id)
GROUP BY man.first_name
  HAVING COUNT (*) > 6;

Tabelul Employees. Arată toți angajații care nu au pe nimeni în subordine
Soluție

SELECT emp.first_name
  FROM employees emp
       LEFT JOIN employees man ON (emp.manager_id = man.employee_id)
 WHERE man.FIRST_NAME IS NULL;

SELECT first_name
  FROM employees
 WHERE manager_id IS NULL;

Tabelul Employees, Job_history. Tabelul Employee conține toți angajații. Tabelul Job_history conține angajații care au părăsit compania. Obțineți un raport despre toți angajații și statutul lor în companie (Lucrează sau a părăsit compania cu data plecării)
Exemplu:
first_name | status
Jennifer | A părăsit compania pe 31 decembrie 2006
Clara | Lucrează în prezent
Soluție

SELECT first_name,
       NVL2 (
           end_date,
           TO_CHAR (end_date, 'fm""A părăsit compania pe"" DD ""din"" Luna, YYYY'),
           'Lucrează în prezent')
           status
  FROM employees e LEFT JOIN job_history j ON (e.employee_id = j.employee_id);

Tabelul Employees, Departaments, Locations, Countries, Regions. Obțineți lista angajaților care locuiesc în Europa (region_name)
Soluție

 SELECT first_name
  FROM employees
       JOIN departments USING (department_id)
       JOIN locations USING (location_id)
       JOIN countries USING (country_id)
       JOIN regions USING (region_id)
 WHERE region_name = 'Europe';
 
 SELECT first_name
  FROM employees e
       JOIN departments d ON (e.department_id = d.department_id)
       JOIN locations l ON (d.location_id = l.location_id)
       JOIN countries c ON (l.country_id = c.country_id)
       JOIN regions r ON (c.region_id = r.region_id)
 WHERE region_name = 'Europe';

Tabelul Employees, Departaments. Afișați toate departamentele în care lucrează mai mult de 30 de angajați
Soluție

SELECT department_name, COUNT (*)
    FROM employees e JOIN departments d ON (e.department_id = d.department_id)
GROUP BY department_name
  HAVING COUNT (*) > 30;

Tabelul Employees, Departaments. Afișați toți angajații care nu fac parte din niciun departament
Soluție

SELECT first_name
  FROM employees e
       LEFT JOIN departments d ON (e.department_id = d.department_id)
 WHERE d.department_name IS NULL;

SELECT first_name
  FROM employees
 WHERE department_id IS NULL;

Tabelul Employees, Departaments. Afișați toate departamentele în care nu există niciun angajat
Soluție

SELECT department_name
  FROM employees e
       RIGHT JOIN departments d ON (e.department_id = d.department_id)
 WHERE first_name IS NULL;

Tabelul Employees. Afișați toți angajații care nu au pe nimeni în subordine
Soluție

SELECT man.first_name
  FROM employees emp
       RIGHT JOIN employees man ON (emp.manager_id = man.employee_id)
 WHERE emp.FIRST_NAME IS NULL;

Tabelul Employees, Jobs, Departaments. Afișați angajații în format: First_name, Job_title, Department_name.
Exemplu:
First_name | Job_title | Department_name
Donald | Shipping | Clerk Shipping
Soluție

SELECT first_name, job_title, department_name
  FROM employees e
       JOIN jobs j ON (e.job_id = j.job_id)
       JOIN departments d ON (d.department_id = e.department_id);

Tabelul Employees. Obțineți lista angajaților ale căror manageri s-au angajat în 2005, dar acești angajați s-au angajat înainte de 2005
Soluție

SELECT emp.*
  FROM employees emp JOIN employees man ON (emp.manager_id = man.employee_id)
 WHERE     TO_CHAR (man.hire_date, 'YYYY') = '2005'
       AND emp.hire_date < TO_DATE ('01012005', 'DDMMYYYY');

Tabelul Angajaților. Obține lista angajaților ai căror manageri au fost angajați în luna ianuarie a oricărui an și lungimea titulului de muncă al acestor angajați este mai mare de 15 caractere.
Soluție

SELECT emp.*
  FROM employees emp
       JOIN employees man ON (emp.manager_id = man.employee_id)
       JOIN jobs j ON (emp.job_id = j.job_id)
 WHERE TO_CHAR (man.hire_date, 'MM') = '01' AND LENGTH (j.job_title) > 15;

Folosind Subinterogări pentru a Rezolva Interogările

Tabelul Angajaților. Obține lista angajaților cu cel mai lung nume.
Soluție

SELECT *
  FROM employees
 WHERE LENGTH (first_name) =
       (SELECT MAX (LENGTH (first_name)) FROM employees);

Tabelul Angajaților. Obține lista angajaților cu un salariu mai mare decât salariul mediu al tuturor angajaților.
Soluție

SELECT *
  FROM employees
 WHERE salary > (SELECT AVG (salary) FROM employees);

Tabelul Angajaților, Departamentelor, Locațiilor. Obține orașul în care angajații câștigă în total cel mai puțin.
Soluție

SELECT city
    FROM employees e
         JOIN departments d ON (e.department_id = d.department_id)
         JOIN locations l ON (d.location_id = l.location_id)
GROUP BY city
  HAVING SUM (salary) =
         (  SELECT MIN (SUM (salary))
              FROM employees e
                   JOIN departments d ON (e.department_id = d.department_id)
                   JOIN locations l ON (d.location_id = l.location_id)
          GROUP BY city);

Tabelul Angajaților. Obține lista angajaților care au manageri cu salarii mai mari de 15000.
Soluție

SELECT *
  FROM employees
 WHERE manager_id IN (SELECT employee_id
                        FROM employees
                       WHERE salary > 15000)

Tabelul Employees, Departaments. Afișați toate departamentele în care nu există niciun angajat
Soluție

SELECT *
  FROM departments
 WHERE department_id NOT IN (SELECT department_id
                               FROM employees
                              WHERE department_id IS NOT NULL);

Tabelul Angajaților. Afișează toți angajații care nu sunt manageri.
Soluție

SELECT *
  FROM employees
 WHERE employee_id NOT IN (SELECT manager_id
                             FROM employees
                            WHERE manager_id IS NOT NULL)

Tabelul Employees. Arată toți managerii care au în subordine mai mult de 6 angajați
Soluție

SELECT *
  FROM employees e
 WHERE (SELECT COUNT (*)
          FROM employees
         WHERE manager_id = e.employee_id) > 6;

Tabelul Angajaților, Departamentelor. Afișează angajații care lucrează în departamentul IT.
Soluție

SELECT *
  FROM employees
 WHERE department_id = (SELECT department_id
                          FROM departments
                         WHERE department_name = 'IT');

Tabelul Employees, Jobs, Departaments. Afișați angajații în format: First_name, Job_title, Department_name.
Exemplu:
First_name | Job_title | Department_name
Donald | Shipping | Clerk Shipping
Soluție

SELECT first_name,
       (SELECT job_title
          FROM jobs
         WHERE job_id = e.job_id)
           job_title,
       (SELECT department_name
          FROM departments
         WHERE department_id = e.department_id)
           department_name
  FROM employees e;

Tabelul Employees. Obțineți lista angajaților ale căror manageri s-au angajat în 2005, dar acești angajați s-au angajat înainte de 2005
Soluție

SELECT *
  FROM employees
 WHERE     manager_id IN (SELECT employee_id
                            FROM employees
                           WHERE TO_CHAR (hire_date, 'YYYY') = '2005')
       AND hire_date < TO_DATE ('01012005', 'DDMMYYYY');

Tabelul Angajaților. Obține lista angajaților ai căror manageri au fost angajați în luna ianuarie a oricărui an și lungimea titulului de muncă al acestor angajați este mai mare de 15 caractere.
Soluție

SELECT *
  FROM employees e
 WHERE     manager_id IN (SELECT employee_id
                            FROM employees
                           WHERE TO_CHAR (hire_date, 'MM') = '01')
       AND (SELECT LENGTH (job_title)
              FROM jobs
             WHERE job_id = e.job_id) > 15;

Asta e tot pentru acum.

Sper că sarcinile au fost interesante și captivante.
Voi completa acest listă de sarcini pe cât posibil.
De asemenea, sunt deschis la orice observații și sugestii.

P.S.: Dacă cineva are o idee interesantă pentru o problemă pe SELECT, vă rog să scrieți în comentarii, o voi adăuga pe lista.

Mulțumim.

Sursa: habr.com

Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS | ProHoster