SQL. Problemi interessanti

Ciao, Habr!

Da oltre 3 anni insegno SQL in diversi centri di formazione, e una delle mie osservazioni è che gli studenti apprendono e comprendono meglio l'SQL se viene presentato loro un compito, piuttosto che semplicemente raccontare le possibilità e le basi teoriche.

In questo articolo condividerò con voi la mia lista di compiti che assegno agli studenti come compiti a casa e sui quali facciamo vari brainstorming, il che porta a una comprensione profonda e chiara dell'SQL.

SQL. Problemi interessanti

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

Puoi leggere di SQL da diverse fonti.
Questo articolo non ha l'obiettivo di insegnarti SQL da zero.

Bene, iniziamo.

Useremo la famosa schema HR in Oracle con le sue tabelle (Ulteriori informazioni):

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

Problemi

Limitare e Ordinare i Dati

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

SELECT * FROM employees

Tabella Employees. Ottenere un elenco di tutti i dipendenti con il nome 'David'
Soluzione

SELECT *
  FROM employees
 WHERE first_name = 'David';

Tabella Employees. Ottenere un elenco di tutti i dipendenti con job_id uguale a 'IT_PROG'
Soluzione

SELECT *
  FROM employees
 WHERE job_id = 'IT_PROG'

Tabella Employees. Ottenere un elenco di tutti i dipendenti del 50° dipartimento (department_id) con stipendio (salary) superiore a 4000
Soluzione

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

Tabella Employees. Ottenere un elenco di tutti i dipendenti del 20° e del 30° dipartimento (department_id)
Soluzione

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

Tabella Employees. Ottenere un elenco di tutti i dipendenti i cui nomi terminano con la lettera 'a'
Soluzione

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

Tabella Employees. Ottenere un elenco di tutti i dipendenti del 50° e dell'80° dipartimento (department_id) che hanno 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 Employees. Ottenere un elenco di tutti i dipendenti i cui nomi contengono almeno 2 lettere 'n'
Soluzione

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

Tabella Employees. Ottenere un elenco di tutti i dipendenti i cui nomi hanno una lunghezza superiore a 4 lettere
Soluzione

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

Tabella Dipendenti. Ottenere l'elenco di tutti i dipendenti la cui retribuzione si trova nell'intervallo tra 8000 e 9000 (incluso)
Soluzione

SELECT *
  FROM employees
 WHERE salary BETWEEN 8000 AND 9000;

Tabella Dipendenti. Ottenere l'elenco di tutti i dipendenti il cui nome contiene il carattere ‘%’
Soluzione

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

Tabella Dipendenti. Ottenere l'elenco di tutti gli ID dei manager
Soluzione

SELECT DISTINCT manager_id
  FROM employees
 WHERE manager_id IS NOT NULL;

Tabella Dipendenti. Ottenere un elenco dei lavoratori con le loro posizioni nel formato: Donald(sh_clerk)
Soluzione

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

Utilizzare Funzioni a Riga Singola per Personalizzare il Risultato

Tabella Dipendenti. Ottenere l'elenco di tutti i dipendenti la cui lunghezza del nome è superiore a 10 caratteri
Soluzione

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

Tabella Dipendenti. Ottenere l'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 Dipendenti. Ottenere l'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 Dipendenti. Ottenere l'elenco di tutti i dipendenti la cui retribuzione è un multiplo di 1000
Soluzione

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

Tabella Dipendenti. Ottenere il primo numero a 3 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. Ottenere la prima parola del nome del dipartimento per quelli che hanno più di una parola nel titolo
Soluzione

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

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

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

Tabella Dipendenti. Ottenere l'elenco di tutti i dipendenti la cui ultima lettera del nome è ‘m’ e la lunghezza del nome è maggiore di 5
Soluzione

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

Tabella Dual. Ottenere la data del prossimo venerdì
Soluzione

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

Tabella Dipendenti. Ottenere l'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. Ottenere l'elenco di tutti i dipendenti la cui ultima cifra del numero di telefono è dispari e consiste in 3 cifre separate da un punto
Soluzione

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

Tabella Employees. Ottenere l'elenco di tutti i dipendenti il cui job_id ha almeno 3 caratteri dopo il segno '_' ma allo stesso tempo questo valore dopo '_' non è uguale a 'CLERK'
Soluzione

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

Tabella Employees. Ottenere l'elenco di tutti i dipendenti sostituendo nel valore PHONE_NUMBER tutti i '.' con '-'
Soluzione

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

Utilizzando Funzioni di Conversione ed Espressioni Condizionali

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

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

Tabella Employees. Ottenere l'elenco di tutti i dipendenti assunti nell'anno 2008
Soluzione

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

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

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

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

SELECT first_name, TO_CHAR (hire_date, 'fmddth ""di"" Mese, YYYY') hire_date
  FROM employees;

Tabella Employees. Ottenere l'elenco dei dipendenti con aumenti di stipendio del 20%. Mostrare 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 Employees. Ottenere l'elenco di tutti i dipendenti assunti nel 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. Restituire 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 Employees. Ottenere l'elenco di tutti i dipendenti con stipendi totali (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 Employees. Ottenere l'elenco di tutti i dipendenti e informazioni sulla presenza di bonus salariali (Sì/No)
Soluzione

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

Tabella Employees. Ottenere il livello di stipendio di ciascun dipendente: Meno di 5000 è considerato di basso livello, Maggiore o uguale a 5000 e minore di 10000 è considerato di livello normale, Maggiore o uguale a 10000 è considerato di alto livello
Soluzione

SELEZIONA first_name,
       stipendio,
       CASE
           WHEN stipendio = 5000 AND stipendio < 10000 THEN 'Normale'
           ELSE 'Alto'
       END livello_stipendio
  DA dipendenti;

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

SELEZIONA country_name paese,
       DECODE (region_id,
               1, 'Europa',
               2, 'America',
               3, 'Asia',
               4, 'Africa',
               'Sconosciuto')
           regione
  DA paesi;

SELEZIONA country_name
           paese,
       CASE region_id
           WHEN 1 THEN 'Europa'
           WHEN 2 THEN 'America'
           WHEN 3 THEN 'Asia'
           WHEN 4 THEN 'Africa'
           ELSE 'Sconosciuto'
       FINE
           regione
  DA paesi;

Reporting Dati Aggregati Utilizzando le Funzioni di Gruppo

Tabella Dipendenti. Ottenere un report per department_id con stipendio minimo e massimo, data di assunzione più precoce e più tardiva e numero di dipendenti. Ordinare per numero di dipendenti (in ordine decrescente)
Soluzione

  SELEZIONA department_id,
         MIN (stipendio) stipendio_minimo,
         MAX (stipendio) stipendio_massimo,
         MIN (hire_date) data_assunzione_min,
         MAX (hire_date) data_assunzione_max,
         CONTA (*) conteggio
    DA dipendenti
GROUP BY department_id
ORDER BY conteggio DESC;

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

SELEZIONA SUBSTR (first_name, 1, 1) primo_carattere, CONTARE (*)
    DA dipendenti
GROUP BY SUBSTR (first_name, 1, 1)
  HAVING CONTARE (*) > 1
ORDER BY 2 DESC;

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

SELEZIONA department_id, stipendio, CONTARE (*)
    DA dipendenti
GROUP BY department_id, stipendio
  HAVING CONTARE (*) > 1;

Tabella Dipendenti. Ottenere un report su quanti dipendenti sono stati assunti in ogni giorno della settimana. Ordinare per numero
Soluzione

SELEZIONA TO_CHAR (hire_Date, 'Giorno') giorno, CONTARE (*)
    DA dipendenti
GROUP BY TO_CHAR (hire_Date, 'Giorno')
ORDER BY 2 DESC;

Tabella Dipendenti. Ottenere un report su quanti dipendenti sono stati assunti per anno. Ordinare per numero
Soluzione

SELEZIONA TO_CHAR (hire_date, 'YYYY') anno, CONTARE (*)
    DA dipendenti
GROUP BY TO_CHAR (hire_date, 'YYYY');

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

SELEZIONA CONTARE (CONTARE (*)) dipartimento_conteggio
    DA dipendenti
   DOVE department_id È NON NULL
GROUP BY department_id;

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

  SELEZIONA department_id
    DA dipendenti
GROUP BY department_id
  HAVING CONTARE (*) > 30;

Tabella Dipendenti. Ottenere l'elenco degli department_id e il salario medio arrotondato dei lavoratori in ogni dipartimento.
Soluzione

  SELEZIONA department_id, ARROTONDA (MEDIA (stipendio)) stipendio_medio
    DA dipendenti
GROUP BY department_id;

Tabella Paesi. Ottenere l'elenco degli region_id somma di tutte le lettere di tutti i country_name in cui sono più di 60
Soluzione

  SELEZIONA region_id
    DA paesi
RAGGRUPPA PER region_id
  AVENDO SOMMA (LUNGHEZZA (country_name)) > 60;

Tabella Employees. Ottenere un elenco di department_id in cui lavorano i dipendenti con più di un job_id
Soluzione

  SELEZIONA department_id
    DA dipendenti
RAGGRUPPA PER department_id
  AVENDO CONTEGGIO (DISTINTI job_id) > 1;

Tabella Employees. Ottenere un elenco di manager_id che hanno più di 5 dipendenti e la somma di tutti gli stipendi dei suoi dipendenti è maggiore di 50000
Soluzione

  SELEZIONA manager_id
    DA dipendenti
RAGGRUPPA PER manager_id
  AVENDO CONTEGGIO (*) > 5 E SOMMA (stipendio) > 50000;

Tabella Employees. Ottenere un elenco di manager_id la cui media degli stipendi di tutti i suoi dipendenti è compresa tra 6000 e 9000 e che non ricevono provvigioni (commission_pct vuoto)
Soluzione

  SELEZIONA manager_id, MEDIA (stipendio) avg_salary
    DA dipendenti
   DOVE commission_pct È NULL
RAGGRUPPA PER manager_id
  AVENDO MEDIA (stipendio) TRA 6000 E 9000;

Tabella Employees. Ottenere lo stipendio massimo tra tutti i dipendenti con job_id che termina con la parola 'CLERK'
Soluzione

SELEZIONA MAX (stipendio) max_salary
  DA dipendenti
 DOVE job_id SIMILE '%CLERK';

SELEZIONA MAX (stipendio) max_salary
  DA dipendenti
 DOVE SUBSTR (job_id, -5) = 'CLERK';

Tabella Employees. Ottenere lo stipendio massimo tra tutte le medie degli stipendi per dipartimento
Soluzione

  SELEZIONA MAX (MEDIA (stipendio))
    DA dipendenti
RAGGRUPPA PER department_id;

Tabella Employees. Ottenere il numero di dipendenti con lo stesso numero di lettere nel nome. Mostrare solo quelli con una lunghezza del nome maggiore di 5 e un numero di dipendenti con quel nome maggiore di 20. Ordinare per lunghezza del nome
Soluzione

  SELEZIONA LUNGHEZZA (first_name), CONTEGGIO (*)
    DA dipendenti
RAGGRUPPA PER LUNGHEZZA (first_name)
  AVENDO LUNGHEZZA (first_name) > 5 E CONTEGGIO (*) > 20
ORDINA PER LUNGHEZZA (first_name);

  SELEZIONA LUNGHEZZA (first_name), CONTEGGIO (*)
    DA dipendenti
   DOVE LUNGHEZZA (first_name) > 5
RAGGRUPPA PER LUNGHEZZA (first_name)
  AVENDO CONTEGGIO (*) > 20
ORDINA PER LUNGHEZZA (first_name);

Visualizzazione Dati da Tabelle Multiple Utilizzando Join

Tabella Employees, Departament, Locations, Countries, Regions. Ottenere un elenco di regioni e il numero di dipendenti in ciascuna regione
Soluzione

  SELEZIONA region_name, CONTEGGIO (*)
    DA dipendenti e
         UNISCITI a dipartimenti d SU (e.department_id = d.department_id)
         UNISCITI a località l SU (d.location_id = l.location_id)
         UNISCITI a paesi c SU (l.country_id = c.country_id)
         UNISCITI a regioni r SU (c.region_id = r.region_id)
RAGGRUPPA PER 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 First_name,
       Last_name,
       Department_name,
       Job_id,
       street_address,
       Country_name,
       Region_name
  DA dipendenti  e
       UNISCITI a dipartimenti d SU (e.department_id = d.department_id)
       UNISCITI a località l SU (d.location_id = l.location_id)
       UNISCITI a paesi c SU (l.country_id = c.country_id)
       UNISCITI a regioni r SU (c.region_id = r.region_id);

Tabella Employees. Mostrare tutti i manager che hanno più di 6 dipendenti sotto di loro
Soluzione

  SELEZIONA man.first_name, CONTEGGIO (*)
    DA dipendenti emp UNISCITI a dipendenti man ON (emp.manager_id = man.employee_id)
RAGGRUPPA PER man.first_name
  HAVENDO CONTEGGIO (*) > 6;

Tabella Dipendenti. Mostra tutti i dipendenti che non rispondono a nessuno
Soluzione

SELEZIONA emp.first_name
  DA dipendenti emp
       SINISTRA UNISCI a dipendenti man ON (emp.manager_id = man.employee_id)
 DOVE man.FIRST_NAME È NULL;

SELEZIONA first_name
  DA dipendenti
 DOVE manager_id È NULL;

Tabella Dipendenti, Storia_lavoro. Nella tabella Dipendenti sono memorizzati tutti i dipendenti. Nella tabella Storia_lavoro sono memorizzati i dipendenti che hanno lasciato l'azienda. Ottieni un report su tutti i dipendenti e sul loro stato nell'azienda (Lavora o ha lasciato l'azienda con la data di uscita)
Esempio:
first_name | stato
Jennifer | Ha lasciato l'azienda il 31 dicembre 2006
Clara | Attualmente in lavorazione
Soluzione

SELEZIONA first_name,
       NVL2 (
           end_date,
           TO_CHAR (end_date, 'fm""Ha lasciato l'azienda il"" DD ""di"" Mese, YYYY'),
           'Attualmente in lavorazione')
           stato
  DA dipendenti e SINISTRA UNISCI storia_lavoro j ON (e.employee_id = j.employee_id);

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

 SELEZIONA first_name
  DA dipendenti
       UNISCITI a dipartimenti UTILIZZANDO (department_id)
       UNISCITI a località UTILIZZANDO (location_id)
       UNISCITI a paesi UTILIZZANDO (country_id)
       UNISCITI a regioni UTILIZZANDO (region_id)
 DOVE region_name = 'Europa';
 
 SELEZIONA first_name
  DA dipendenti e
       UNISCITI a dipartimenti d ON (e.department_id = d.department_id)
       UNISCITI a località l ON (d.location_id = l.location_id)
       UNISCITI a paesi c ON (l.country_id = c.country_id)
       UNISCITI a regioni r ON (c.region_id = r.region_id)
 DOVE region_name = 'Europa';

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

SELEZIONA department_name, CONTEGGIO (*)
    DA dipendenti e UNISCITI a dipartimenti d ON (e.department_id = d.department_id)
RAGGRUPPA PER department_name
  HAVENDO CONTEGGIO (*) > 30;

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

SELEZIONA first_name
  DA dipendenti e
       SINISTRA UNISCI a dipartimenti d ON (e.department_id = d.department_id)
 DOVE d.department_name È NULL;

SELEZIONA first_name
  DA dipendenti
 DOVE department_id È NULL;

Tabella Dipendenti, Dipartimenti. Mostra tutti i dipartimenti in cui non c'è nessun dipendente
Soluzione

SELEZIONA department_name
  DA dipendenti e
       DESTRA UNISCI a dipartimenti d ON (e.department_id = d.department_id)
 DOVE first_name È NULL;

Tabella Dipendenti. Mostra tutti i dipendenti che non hanno nessuno a cui rispondere
Soluzione

SELEZIONA man.first_name
  DA dipendenti emp
       DESTRA UNISCI a dipendenti man ON (emp.manager_id = man.employee_id)
 DOVE emp.FIRST_NAME È NULL;

Tabella Dipendenti, Lavori, Dipartimenti. 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 dipendenti e
       UNISCITI a lavori j ON (e.job_id = j.job_id)
       UNISCITI a dipartimenti d ON (d.department_id = e.department_id);

Tabella Dipendenti. Ottieni un elenco dei dipendenti i cui manager sono stati assunti nel 2005, ma questi stessi lavoratori sono stati assunti prima del 2005
Soluzione

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

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

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;

Utilizzo delle Sottoquery per Risolvere le Query

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

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

Tabella Employees. Ottenere un elenco di 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 Employees, Departments, Locations. 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 Employees. Ottenere un elenco di dipendenti i cui manager guadagnano 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 c'è nessun dipendente
Soluzione

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

Tabella Employees. 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 Employees. Mostrare tutti i manager che hanno più di 6 dipendenti sotto di loro
Soluzione

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

Tabella Employees, Departaments. Mostrare i dipendenti che lavorano nel dipartimento IT.
Soluzione

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

Tabella Dipendenti, Lavori, Dipartimenti. Mostra i dipendenti nel formato: First_name, Job_title, Department_name.
Esempio:
First_name | Job_title | Department_name
Donald | Spedizione | Impiegato Spedizione
Soluzione

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;

Tabella Dipendenti. Ottieni un elenco dei dipendenti i cui manager sono stati assunti nel 2005, ma questi stessi lavoratori sono stati assunti prima del 2005
Soluzione

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

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

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;

Per ora è tutto.

Spero che i compiti siano stati interessanti e coinvolgenti.
Farò del mio meglio per ampliare questa lista di compiti.
Sarò anche felice di ricevere qualsiasi commento o suggerimento.

P.S.: Se a qualcuno viene in mente un compito interessante su SELECT, scrivete nei commenti, lo aggiungerò alla lista.

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