query SQL che coinvolgono 'per tutti' [chiusa]
-
25-10-2019 - |
Domanda
Non ho potuto avere un suggerimento su come scrivere query SQL per A e B per il seguente schema.
Programme (Pid:int, Department:string...)
Employee (Eid:int, Department:string..)
Participation (Pid:int, Eid:int, ..)
A. I nomi dei programmi hanno partecipato da tutti i dipendenti
B. I nomi dei dipendenti che aderiscono a tutti i suoi di reparto programmi.
Le eventuali linee guida sarebbe utile.
Soluzione
Non ho provato questi, ma questo è quello che vorrei pensare:
SELECT pg.Name
FROM Participation AS p INNER JOIN Programme AS pg ON p.Pid = pg.Pid
GROUP BY p.Pid
HAVING COUNT(*) = (SELECT COUNT(*) FROM Employeee)
SELECT e.Name
FROM Participation AS p INNER JOIN Employee AS e ON p.Eid = e.Eid
INNER JOIN Programme AS pg ON pg.Pid = p.Pid
WHERE pg.Department = e.Department
GROUP BY p.Eid, e.Department, e.Name
HAVING COUNT(*) = (SELECT COUNT(*)
FROM Programme AS pg2
WHERE pg2.Department = e.Department)
Altri suggerimenti
L'operatore relazionale che si richiede è , popolarmente conosciuta come "il fornitore che fornisce tutte le parti" .
Cose da considerare sono se esatta scissione o la scissione con resto e come gestire un divisore vuoto.
UPDATE: solo per chiarire, SQL manca un operatore di divisione esplicita o parola chiave **. Tuttavia, divisione relazionale può essere realizzato in SQL utilizzando altri operatori. Mi astengo dal pubblicare un esempio di lavoro a causa del tag 'compiti a casa'. Ma quello che io di solito uso è simile alla "Divisione con Set operatori" esempio a questo link .
Si noti che di @Dylan Smith è ciò che è comunemente noto come "la divisione di Celko" e @ risposta di tobyodavies utilizza una variazione su ciò che è comunemente noto come "la divisione di Data" (data non avrebbe usato un outer join ma invece un secondo NOT EXISTS
) . Ma forse hanno davvero fatto reinventare questi stessi approcci ben consolidati, chi lo sa? ;)
** lo stesso vale per molti altri operatori relazionali esempio SQL ha alcun operatore semi-differenza, ma può essere eseguita con altri operatori SQL esempio NOT IN
, NOT EXISTS
, EXCEPT
, ecc.
Usa WHERE NOT EXISTS
e outer join
per tutti i programmi universali:
SELECT * FROM Programme
WHERE NOT EXISTS (SELECT * FROM
(Participation NATURAL JOIN Programme) LEFT JOIN Employee
USING (Eid,Department)
WHERE Employee.Eid IS NULL)
Questo dovrebbe essere abbastanza facile da spiegare - seleziona tutti i programmi in cui il è nessun dipendente che non partecipano
Per tutti i dipendenti enthusiatic:
SELECT * FROM Employee
WHERE NOT EXISTS (SELECT * FROM
Employee LEFT JOIN Participation
USING (Eid,department)
WHERE Participation.Eid IS NULL)
Ancora una volta -. Seleziona tutti employyes dove non ci sono programmi nella stessa reparto in cui il dipendente non partecipa
Questo può sembrare familiare se si ha familiarità con la logica formale a tutti - la quantificazione universale è generalmente definito in termini di negata esistenziale qualificazione