SQL. Problemi interessanti

Ciao, Habr!

Da oltre 3 anni insegno SQL in vari centri di formazione, e una delle mie osservazioni è che gli studenti apprendono e comprendono meglio SQL se gli vengono posti dei compiti, piuttosto che limitarsi a raccontare le possibilità e le basi teoriche.

In questo articolo condividerò con voi la mia lista di compiti che assegno agli studenti come esercizi a casa su cui facciamo diversi brainstorming, il che porta a una comprensione profonda e chiara di SQL.

SQL. Problemi interessanti

SQL (ˈɛsˈkjuˈɛl; inglese: structured query language — «linguaggio di interrogazione strutturata») è un linguaggio di programmazione dichiarativo utilizzato per creare, modificare e gestire dati in un database relazionale controllato dal corrispondente sistema di gestione dei database. Maggiori informazioni…

Puoi leggere di SQL in diversi sorgenti.
Questo articolo non ha l'obiettivo di insegnarti SQL da zero.

Dunque, andiamo.

Useremo la noto schema HR in Oracle con le sue tabelle (Scopri di più):

SQL. Problemi interessanti
Nota che considereremo solo compiti basati su SELECT. Non ci sono compiti su DML e DDL.

Attività

Limitare e Ordinare i Dati

Tabella Employees. Ottieni un elenco con le informazioni su tutti i dipendenti.
Soluzione

SELECT * FROM employees

Tabella Dipendenti. Ottieni l'elenco di tutti i dipendenti con il nome 'David'
Soluzione

SELECT *
  FROM employees
 WHERE first_name = 'David';

Tabella Dipendenti. Ottieni l'elenco di tutti i dipendenti con job_id uguale a 'IT_PROG'
Soluzione

SELECT *
  FROM employees
 WHERE job_id = 'IT_PROG';

Tabella Dipendenti. Ottieni l'elenco di tutti i dipendenti del 50° reparto (department_id) con stipendio (salary) maggiore di 4000
Soluzione

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

Tabella Dipendenti. Ottieni l'elenco di tutti i dipendenti del 20° e del 30° reparto (department_id)
Soluzione

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

Tabella Dipendenti. Ottieni l'elenco di tutti i dipendenti il cui nome termina con la lettera 'a'
Soluzione

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

Tabella Dipendenti. Ottieni l'elenco di tutti i dipendenti del 50° e dell'80° reparto (department_id) che hanno un bonus (valore nella colonna commission_pct non vuoto)
Soluzione

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

Tabella Dipendenti. Ottieni l'elenco di tutti i dipendenti i cui nomi contengono almeno 2 lettere 'n'
Soluzione

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

Tabella Dipendenti. Ottieni l'elenco di tutti i dipendenti i cui nomi superano le 4 lettere
Soluzione

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

Tabella Employees. Ottieni un elenco di tutti i dipendenti il cui stipendio è compreso tra 8000 e 9000 (incluso)
Soluzione

SELECT *
  FROM employees
 WHERE salary BETWEEN 8000 AND 9000;

Tabella Employees. Ottieni un elenco di tutti i dipendenti il cui nome contiene il carattere ‘%’
Soluzione

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

Tabella Employees. Ottieni un elenco di tutti gli ID dei manager
Soluzione

SELECT DISTINCT manager_id
  FROM employees
 WHERE manager_id IS NOT NULL;

Tabella Employees. Ottieni un elenco dei dipendenti con le loro posizioni nel formato: Donald(sh_clerk)
Soluzione

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

Utilizzo di funzioni a riga singola per personalizzare l'output

Tabella Employees. Ottieni un elenco di tutti i dipendenti il cui nome è lungo più di 10 lettere
Soluzione

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

Tabella Employees. Ottieni un elenco di tutti i dipendenti il cui nome contiene la lettera ‘b’ (senza distinzione tra maiuscole e minuscole)
Soluzione

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

Tabella Employees. Ottieni un elenco di tutti i dipendenti il cui nome contiene almeno 2 lettere ‘a’
Soluzione

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

Tabella Employees. Ottieni un elenco di tutti i dipendenti il cui stipendio è un multiplo di 1000
Soluzione

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

Tabella Dipendenti. Ottieni le prime tre cifre del numero di telefono del dipendente se il suo numero è nel formato XXX.XXX.XXXX
Soluzione

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

Tabella Dipartimenti. Ottieni la prima parola dal nome del dipartimento per coloro che hanno un nome con più di una parola
Soluzione

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

Tabella Dipendenti. Ottieni i nomi dei dipendenti senza la prima e l'ultima lettera del nome
Soluzione

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

Tabella Dipendenti. Ottieni un elenco di tutti i dipendenti il cui nome termina con ‘m’ e la cui lunghezza del nome è maggiore di 5
Soluzione

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

Tabella Dual. Ottieni la data del prossimo venerdì
Soluzione

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

Tabella Dipendenti. Ottieni un elenco di tutti i dipendenti che lavorano in azienda da più di 17 anni
Soluzione

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

Tabella Dipendenti. Ottieni un elenco di tutti i dipendenti il cui ultimo numero di telefono è dispari e composto da 3 cifre separate da un punto
Soluzione

SELEZIONA *
  DA impiegati
 DOVE     MOD (SUBSTR (numero_di_telefono, -1), 2) != 0
       E INSTR (numero_di_telefono,'.',1,3) = 0;

Tabella Impiegati. Ottieni l'elenco di tutti i dipendenti il cui valore di job_id dopo il simbolo '_' ha almeno 3 caratteri, ma questo valore dopo '_' non deve essere 'CLERK'
Soluzione

SELEZIONA *
  DA impiegati
 DOVE     LUNGHEZZA (SUBSTR (job_id, INSTR (job_id, '_') + 1)) > 3
       E SUBSTR (job_id, INSTR (job_id, '_') + 1) != 'CLERK';

Tabella Impiegati. Ottieni l'elenco di tutti i dipendenti sostituendo nel valore PHONE_NUMBER tutti i ‘.’ con ‘-‘
Soluzione

SELEZIONA numero_di_telefono, REPLACE (numero_di_telefono, '.', '-') nuovo_numero_di_telefono
  DA impiegati;

Utilizzando Funzioni di Conversione ed Espressioni Condizionali

Tabella Impiegati. Ottieni l'elenco di tutti i dipendenti che sono stati assunti il primo giorno del mese (qualsiasi)
Soluzione

SELEZIONA *
  DA impiegati
 DOVE TO_CHAR (data_assunzione, 'DD') = '01';

Tabella Impiegati. Ottieni l'elenco di tutti i dipendenti assunti nel 2008
Soluzione

SELEZIONA *
  DA impiegati
 DOVE TO_CHAR (data_assunzione, 'YYYY') = '2008';

Tabella DUAL. Mostra la data di domani nel formato: Domani è il secondo giorno di gennaio
Soluzione

SELEZIONA TO_CHAR (SYSDATE, 'fm""Domani è ""Ddspth ""giorno di"" Mese') info
  DA DUAL;

Tabella Impiegati. Ottieni l'elenco di tutti i dipendenti e la data di assunzione di ciascuno nel formato: 21st di Giugno, 2007
Soluzione

SELEZIONA nome, TO_CHAR (data_assunzione, 'fmddth ""di"" Mese, YYYY') data_assunzione
  DA impiegati;

Tabella Dipendenti. Ottieni l'elenco dei lavoratori con un aumento del 20% degli stipendi. Mostra lo stipendio con il simbolo del dollaro
Soluzione

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

Tabella Dipendenti. Ottieni l'elenco di tutti i dipendenti assunti a febbraio 2007.
Soluzione

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'; 

Tabella DUAL. Restituisci la data attuale, + secondo, + minuto, + ora, + giorno, + mese, + anno
Soluzione

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;

Tabella Dipendenti. Ottieni l'elenco di tutti i dipendenti con stipendio totale (salary + commission_pct(%)) nel formato: $24,000.00
Soluzione

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

Tabella Dipendenti. Ottieni l'elenco di tutti i dipendenti e le informazioni sulla presenza di bonus sullo stipendio (Sì/No)
Soluzione

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

Tabella Dipendenti. Ottenere il livello salariale di ogni dipendente: Meno di 5000 è considerato basso, Maggiore o uguale a 5000 e meno di 10000 è considerato normale, Maggiore o uguale a 10000 è considerato alto.
Soluzione

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

Tabella Paesi. Mostrare per ogni paese la regione in cui si trova: 1-Europa, 2-America, 3-Asia, 4-Africa (senza Join)
Soluzione

SELECT country_name country,
       DECODE (region_id,
               1, 'Europa',
               2, 'America',
               3, 'Asia',
               4, 'Africa',
               'Sconosciuto')
           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 'Sconosciuto'
       END
           region
  FROM countries;

Reporting Dati Aggregati Utilizzando le Funzioni di Gruppo

Tabella Dipendenti. Ottenere un report per department_id con il salario minimo e massimo, con la data di assunzione più antica e più recente e con il numero di dipendenti. Ordinare per numero di dipendenti (in modo decrescente).
Soluzione

  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;

Tabella Dipendenti. Quanti dipendenti hanno nomi che iniziano con la stessa lettera? Ordinare per quantità. Mostrare solo quelli dove la quantità è maggiore di 1
Soluzione

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;

Tabella Dipendenti. Quanti dipendenti lavorano nello stesso dipartimento e guadagnano lo stesso stipendio?
Soluzione

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

Tabella Dipendenti. Ottenere un report di quanti dipendenti sono stati assunti ogni giorno della settimana. Ordinare per quantità
Soluzione

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

Tabella Dipendenti. Ottenere un report di quanti dipendenti sono stati assunti per anni. Ordinare per quantità
Soluzione

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

Tabella Dipendenti. Ottenere il numero di dipartimenti in cui ci sono dipendenti
Soluzione

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

Tabella Dipendenti. Ottenere l'elenco di department_id in cui lavorano più di 30 dipendenti
Soluzione

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

Tabella Dipendenti. Ottenere un elenco di department_id e lo stipendio medio arrotondato dei dipendenti in ciascun dipartimento.
Soluzione

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

Tabella Paesi. Ottenere un elenco di region_id con la somma totale dei caratteri di tutti i country_name che superano i 60.
Soluzione

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

Tabella Dipendenti. Ottenere un elenco di department_id in cui lavorano dipendenti con diversi (>1) job_id.
Soluzione

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

Tabella Dipendenti. Ottenere un elenco di manager_id che hanno più di 5 subordinati e la somma di tutti gli stipendi dei loro subordinati supera 50000.
Soluzione

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

Tabella Dipendenti. Ottenere un elenco di manager_id la cui media salariale di tutti i suoi subordinati è compresa tra 6000 e 9000 e che non ricevono bonus (commission_pct vuoto).
Soluzione

  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;

Tabella Dipendenti. Ottenere lo stipendio massimo di tutti i dipendenti il cui job_id termina con la parola 'CLERK'.
Soluzione

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';

Tabella Employees. Ottenere il salario massimo tra tutte le medie salariali per departmento
Soluzione

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

Tabella Employees. Ottenere il numero di dipendenti con lo stesso numero di lettere nel nome. Mostrare solo coloro che hanno un nome lungo più di 5 e un numero di dipendenti con quel nome superiore a 20. Ordinare per lunghezza del nome
Soluzione

  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);

Visualizzazione dei dati da più tabelle utilizzando i join

Tabella Employees, Departaments, Locations, Countries, Regions. Ottenere l'elenco delle regioni e il numero di dipendenti in ogni regione
Soluzione

  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;

Tabella Employees, Departaments, Locations, Countries, Regions. Ottenere informazioni dettagliate su ciascun dipendente:
First_name, Last_name, Departament, Job, Street, Country, Region
Soluzione

SELEZIONA Nome,
       Cognome,
       Nome_del_Dipartimento,
       ID_Lavoro,
       Indirizzo,
       Nome_del_Paese,
       Nome_della_Regione
  DA impiegati e
       UNISCI dipartimenti d ON (e.id_dipartimento = d.id_dipartimento)
       UNISCI posizioni l ON (d.id_posizione = l.id_posizione)
       UNISCI paesi c ON (l.id_paese = c.id_paese)
       UNISCI regioni r ON (c.id_regione = r.id_regione);

Tabella Dipendenti. Mostra tutti i manager che hanno sotto di sé più di 6 dipendenti
Soluzione

  SELEZIONA man.nome, CONTA (*)
    DA impiegati emp UNISCI impiegati man ON (emp.id_manager = man.id_impiegato)
GROUP BY man.nome
  HAVENDO CONTA (*) > 6;

Tabella Dipendenti. Mostra tutti i dipendenti che non hanno sotto di sé nessuno
Soluzione

SELEZIONA emp.nome
  DA impiegati emp
       UNIONE SINISTRA impiegati man ON (emp.id_manager = man.id_impiegato)
 DOVE man.NOME È NULL;

SELEZIONA nome
  DA impiegati
 DOVE id_manager È NULL;

Tabella Dipendenti, Storico_Lavoro. Nella tabella Dipendenti sono conservati tutti i dipendenti. Nella tabella Storico_Lavoro sono conservati i dipendenti che hanno lasciato l'azienda. Ottenere un rapporto su tutti i dipendenti e sul loro stato in azienda (Lavora o ha lasciato l'azienda con data di uscita)
Esempio:
nome | stato
Jennifer | Ha lasciato l'azienda il 31 dicembre 2006
Clara | Attualmente Lavorando
Soluzione

SELEZIONA nome,
       NVL2 (
           data_fine,
           TO_CHAR (data_fine, 'fm""Ha lasciato l'azienda il"" DD ""di"" Mese, YYYY'),
           'Attualmente Lavorando')
           stato
  DA impiegati e UNISCI storico_lavoro j ON (e.id_impiegato = j.id_impiegato);

Tabella Dipendenti, Dipartimenti, Località, Paesi, Regioni. Ottieni l'elenco dei dipendenti che vivono in Europa (region_name)
Soluzione

 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';

Tabella Dipendenti, Dipartimenti. Mostra tutti i dipartimenti in cui lavorano più di 30 dipendenti
Soluzione

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

Tabella Dipendenti, Dipartimenti. Mostra tutti i dipendenti che non appartengono a nessun dipartimento
Soluzione

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;

Tabella Dipendenti, Dipartimenti. Mostra tutti i dipartimenti in cui non ci sono dipendenti
Soluzione

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

Tabella Dipendenti. Mostra tutti i dipendenti che non hanno nessuno sotto di loro
Soluzione

SELEZIONA man.first_name
  DA employees emp
       JOIN RIGHT employees man SU (emp.manager_id = man.employee_id)
 DOVE emp.FIRST_NAME È NULL;

Tabella Employees, Jobs, Departments. Mostra i dipendenti nel formato: First_name, Job_title, Department_name.
Esempio:
First_name | Job_title | Department_name
Donald | Spedizione | Impiegato Spedizione
Soluzione

SELEZIONA first_name, job_title, department_name
  DA employees e
       JOIN jobs j SU (e.job_id = j.job_id)
       JOIN departments d SU (d.department_id = e.department_id);

Tabella Employees. Ottenere un elenco dei dipendenti i cui manager sono stati assunti nel 2005, ma questi dipendenti sono stati assunti prima del 2005.
Soluzione

SELEZIONA emp.*
  DA employees emp JOIN employees man SU (emp.manager_id = man.employee_id)
 DOVE     TO_CHAR (man.hire_date, 'YYYY') = '2005'
       E emp.hire_date < TO_DATE ('01012005', 'DDMMYYYY');

Tabella Employees. Ottenere un elenco dei dipendenti i cui manager sono stati assunti nel mese di gennaio di qualsiasi anno e la lunghezza del job_title di questi dipendenti è superiore a 15 caratteri.
Soluzione

SELEZIONA emp.*
  DA employees emp
       JOIN employees man SU (emp.manager_id = man.employee_id)
       JOIN jobs j SU (emp.job_id = j.job_id)
 DOVE TO_CHAR (man.hire_date, 'MM') = '01' E LENGTH (j.job_title) > 15;

Utilizzare le sottoquery per risolvere le query

Tabella Employees. Ottenere un elenco dei dipendenti con il nome più lungo.
Soluzione

SELEZIONA *
  DA employees
 DOVE LENGTH (first_name) =
       (SELEZIONA MAX (LENGTH (first_name)) DA employees);

Tabella Dipendenti. Ottenere un elenco dei dipendenti con uno stipendio superiore alla media degli stipendi di tutti i dipendenti.
Soluzione

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

Tabella Dipendenti, Dipartimenti, Luoghi. Ottenere la città in cui i dipendenti guadagnano meno in totale.
Soluzione

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);

Tabella Dipendenti. Ottenere un elenco dei dipendenti il cui manager guadagna più di 15000.
Soluzione

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

Tabella Dipendenti, Dipartimenti. Mostra tutti i dipartimenti in cui non ci sono dipendenti
Soluzione

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

Tabella Dipendenti. Mostrare tutti i dipendenti che non sono manager.
Soluzione

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

Tabella Dipendenti. Mostra tutti i manager che hanno sotto di sé più di 6 dipendenti
Soluzione

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

Tabella Dipendenti, Dipartimenti. Mostrare i dipendenti che lavorano nel dipartimento IT.
Soluzione

SELEZIONA *
  DA impiegati
 DOVE department_id = (SELEZIONA department_id
                          DA reparti
                         DOVE department_name = 'IT');

Tabella Employees, Jobs, Departments. Mostra i dipendenti nel formato: First_name, Job_title, Department_name.
Esempio:
First_name | Job_title | Department_name
Donald | Spedizione | Impiegato Spedizione
Soluzione

SELEZIONA first_name,
       (SELEZIONA job_title
          DA lavori
         DOVE job_id = e.job_id)
           job_title,
       (SELEZIONA department_name
          DA reparti
         DOVE department_id = e.department_id)
           department_name
  DA impiegati e;

Tabella Employees. Ottenere un elenco dei dipendenti i cui manager sono stati assunti nel 2005, ma questi dipendenti sono stati assunti prima del 2005.
Soluzione

SELEZIONA *
  DA impiegati
 DOVE     manager_id IN (SELEZIONA employee_id
                            DA impiegati
                           DOVE TO_CHAR (hire_date, 'YYYY') = '2005')
       E hire_date < TO_DATE ('01012005', 'DDMMYYYY');

Tabella Employees. Ottenere un elenco dei dipendenti i cui manager sono stati assunti nel mese di gennaio di qualsiasi anno e la lunghezza del job_title di questi dipendenti è superiore a 15 caratteri.
Soluzione

SELEZIONA *
  DA impiegati e
 DOVE     manager_id IN (SELEZIONA employee_id
                            DA impiegati
                           DOVE TO_CHAR (hire_date, 'MM') = '01')
       E (SELEZIONA LENGTH (job_title)
              DA lavori
             DOVE job_id = e.job_id) > 15;

Questo è tutto per ora.

Spero che le sfide siano state interessanti e coinvolgenti.
Cercherò di aggiungere questo elenco di compiti quando possibile.
Sarei anche felice di ricevere qualsiasi commento e suggerimento.

P.S.: Se a qualcuno viene in mente un compito interessante su SELECT, scrivetelo nei commenti, lo aggiungerò all'elenco.

Grazie.

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster