2012-04-09 10 views
0

Ich brauche Hilfe! Zum Beispiel gibt es vier Tabellen: Autos, Benutzer, Abteilungen und join_user_department. Letzte Tabelle, die für die M: N-Beziehung zwischen den Tabellen Benutzer und Abteilung verwendet wird, da einige Benutzer nur eingeschränkten Zugriff haben. Ich muss die Anzahl der Autos in Abteilungen abrufen, in denen Benutzer Zugriff haben. Die Tabelle "Autos" hat eine Spalte department_id. Wenn die Tabelle join_user_department keinen Eintrag von user_id hat, bedeutet dies, dass er Zugriff auf alle Abteilungen hat und die Abfrage muss ohne Bedingung sein. Ich brauche so etwas zu tun:wählen Sie die Abfrage mit, wenn in Oracle

declare 
DEP_NUM number;--count of departments where user have access 
CARS_COUNT number;--count of cars 
BEGIN 
SELECT COUNT (*) into DEP_NUM from join_user_departments where user_id=?; 
SELECT COUNT(*) into CARS_COUNT FROM cars where 
    IF(num!=0)—it meant that user access is limited 
    THEN department_id IN (select dep_id from join_user_departments where user_id=?); 

Antwort

2

Ein Benutzer entweder hat Zugriff auf alle Autos (Ich gehe davon aus alle Autos an eine Abteilung gebunden sind, und der Benutzer hat Zugriff auf alle Abteilungen) oder der Benutzer hat nur begrenzten Zugang . Sie können UNION ALL verwenden, um diese beiden Gruppen zusammenzufassen, und nach Benutzer gruppieren, um eine abschließende Zählung durchzuführen. Ich habe Kreuz die Benutzer mit unbegrenzten Zugriff auf den Wagen Tisch gesellte sich zu ihnen mit allen Autos zu assoziieren:

(AKTUALISIERT auch die Abteilungen zählen)

select user_id, 
    count(distinct department_id) as dept_count, 
    count(distinct car_id) as car_count, 
from (
    select ud.user_id, ud.department_id, c.car_id 
    from user_departments ud 
    join cars c on c.department_id = ud.department_id 
    UNION ALL 
    select u.user_id, v.department_id, v.car_id 
    from user u 
    cross join (
     select d.department_id, c.car_id 
     from department d 
     join cars c on c.department_id = d.department_id 
    ) v 
    where not exists (
     select 1 from user_departments ud 
     where ud.user_id = u.user_id 
    ) 
) 
group by user_id 

A UNION ALL, dass eine UNION effizienter ist; Eine UNION sucht nach Datensätzen, die in beide Gruppen fallen und verwirft Duplikate. Da jeder Benutzer in den einen oder anderen Bucket fällt, sollte UNION ALL den Trick machen (das Ausführen einer eindeutigen Zählung in der äußeren Abfrage schließt auch Dubletten aus).

1

„Wenn die Tabelle join_user_department keine Aufzeichnung von User_id hat bedeutet dies, dass er Zugang zu allen Abteilungen haben“

Das ist wie sehr schlechte Praxis scheint. Im Wesentlichen verwenden Sie die Abwesenheit von Datensätzen, um das Vorhandensein von Datensätzen zu simulieren. Sehr unordentlich. Was passiert, wenn ein Benutzer keinen Zugang zu einem Auto von einer Abteilung hat? Vielleicht erlaubt die aktuelle Geschäftslogik das nicht, aber Sie haben ein "Datenmodell", das es nicht erlaubt, ein solches Szenario zu implementieren, ohne die Logik Ihrer Anwendung zu ändern.

+0

Guter Punkt. In der Datenbank sollte ein Flag vorhanden sein, das explizit den vollen Zugriff für einen Benutzer gewährt. –