2016-03-30 13 views
1

SQL FIDDLE DEMO HEREWie kann ich Case für diese Abfrage auswählen?

Ich habe diese Struktur von Tabellen:

CREATE TABLE Users 

      ([UserId] int, 
      [IdDepartment] int); 

    INSERT INTO Users 
     ([UserId], [IdDepartment]) 
    VALUES 
     (1, 5), 
     (2, 0), 
     (3, -1), 
     (4, 0), 
     (5, -1), 
     (6, 0); 

    CREATE TABLE Department 
     ([IdDepartment] int, [Name] varchar(23), [IdUser] int); 

    INSERT INTO Department 
     ([IdDepartment], [Name], [IdUser]) 
    VALUES 
     (1, 'Sales', 3), 
     (2, 'Finance', null), 
     (3, 'Accounting' , 5), 
     (4, 'IT' ,3), 
     (5, 'Secretary',null), 
     (6, 'Sport',3); 

Ich mag eine Abfrage mit diesen Ergebnissen erhalten: In der Tabelle Benutzer, wenn die IdDepartment 0 ist, bedeutet, dass der Benutzer ein Administrator ist so Er kann alle Abteilungen sehen. Wenn der Benutzer eine -1 in der IDpartment hat, bedeutet dies, dass der Benutzer auf begrenzte Abteilungen zugreifen kann. In diesem Fall mache ich einen inneren Join zur Abteilungstabelle, um die Liste dieser Abteilungen zu erhalten. Der letzte Fall ist, wenn der Benutzer eine Nummer für das idDepartament in der Benutzertabelle hat, die von 0 verschieden ist und sich von -1 unterscheidet, bedeutet dies, dass der Benutzer nur auf diese Abteilung zugreifen kann.

Ich habe versucht, so etwas zu tun, aber es ist nicht gut strukturiert:

select 
    case idDepartment 
     when 0 then (select Name from Department) 
     when -1 then (select Name from Department where IdUser = 3) 
     else   (select Name from Department 
         inner join Users on Department.idDepartment = Users.Department   
         where Users.UserId = 3) 
    end 
from 
    Department 
where 
    IdUser = 3 

Wie kann ich das tun? Vielen Dank.

füge ich ein Beispiel für das, was ich zu bekommen:

-For the user that has the userid (1) --> 

    Department Name 
    --------------- 
    Secretary 




-For the user that has the userid (2) --> 

    Department Name 
    --------------- 
    Sales 
    Finance 
    Accounting 
    IT 
    Secretary 
    Sport 




-For the user that has the userid (3) --> 

    Department Name 
    --------------- 
    Sales 
    IT 
    Sports 
+4

Dies überhaupt keinen Sinn machen. Sie haben eine großartige Arbeit geleistet, indem Sie ddl und Beispieldaten gepostet haben. Ich wünschte, jeder würde so einen netten Job machen. Was wäre der erwartete Output davon? –

+0

Kannst du das Ergebnis auch posten –

+0

Dies ist ein kleines Beispiel für das, was ich brauche, aber ich mache dieses Beispiel, um zu wissen, wie man den ausgewählten Fall behandelt –

Antwort

1
declare @IdUser int = 3; 
    SELECT u.[UserId], d.Name 
    from Users u 
    join Department d 
     on u.[IdDepartment] = 0 
     or (u.[IdDepartment] = -1 and d.[IdUser]  = u.[UserId]) 
     or (u.[IdDepartment] > 0 and d.[IdDepartment] = u.[IdDepartment]) 
    where u.[UserId] = @IdUser 
    order by u.[UserId], d.Name 

userID 3 sollte Sport gehören

+0

Zwei down votes. Hast du das getestet? Ich tat. – Paparazzi

+0

Dein Code funktioniert mir auch richtig, danke für deine Hilfe ;-D –

2

Sie kann nicht in einem SELECT CASE etwas tun, ist die beste Option, um nur einige Logik einführen

DECLARE @IdUser INT = 3 
DECLARE @userDepartment INT 
SELECT @userDepartment = IdDepartment 
FROM Users 
WHERE UserId = @IdUser 

IF @userDepartment = 0 
BEGIN 
    SELECT Name FROM Department 
END 
ELSE IF @userDepartment = -1 
BEGIN 
    SELECT Name FROM Department WHERE IdUser = @IdUser 
END 
ELSE 
BEGIN 
    SELECT Name FROM Department 
    INNER JOIN Users 
     ON Department.idDepartment = Users.IdDepartment 
    WHERE Users.UserId = @IdUser 
END 

Übrigens, Sie haben getroffen, warum Ihre Struktur nicht ideal ist. Wenn Sie eine Junction-Tabelle zwischen Benutzern hatten, könnten Sie eine beliebige Kombination aus dem, was Sie bereits haben, mit einer viel einfacheren Abfrage modellieren. (Auf Kosten von vielen Zeilen in Ihrer Junction-Tabelle)

+0

Danke für deine Hilfe, es funktioniert einwandfrei ;-D –

2

Ihr Beispielcode ist ein wenig verwirrend aber fühlt sich an wie Sie für so etwas suchen:

declare @id_user int = 3 

select d.IdDepartment, d.Name 
from Department d 
where exists 
    (
    select 1 
    from Users u 
    where u.[UserId] = @id_user 
     and u.IdDepartment in (0, d.IdDepartment) 
) 
    or d.[IdUser] = @id_user 

, die implementiert:

  • wenn IdUser in Department Tabelle ist die gleiche wie @id_user gegeben - er Zugang hat th Abteilung sicher
  • sonst dieser Benutzer ist der Zugang zu Abteilung hat, wenn sein Wert IdDep

Aber Ihre Rechte/Sicherheitsmodell 0 oder gleich entsprechenden ID-Abteilung ist riecht nicht gut, und es ist absolut nicht skalierbar. Sie sollten eine andere Entität (Tabelle) erfinden, um erlaubte Tupel zu speichern: (IdUser, IdDepartment). Select-Anweisungen würden in diesem Fall viel klarer aussehen.

+0

funktioniert dein Code einwandfrei, danke für deine Hilfe :-) –

-1

Wenn ich von Ihrer pseudo-Abfrage zu verstehen, was Sie zu tun versuchen, können Sie es mit einer sorgfältig tun konstruiert WHERE-Klausel:

case idDepartment 
    when 0 then (select Name from Department) 
    when -1 then (select Name from Department where IdUser = 3) 
    else (select Name from Department inner join Users on  Department.idDepartment = Users.Department where Users.UserId = 3) 
end 

könnte als Unterauswahl geschrieben werden:

(SELECT Name 
FROM Department 
LEFT OUTER JOIN Users 
    on  Department.idDepartment = Users.Department 
WHERE idDepartment=0 
OR (idDepartment = -1 AND idUser = 3) 
OR (Users.UserId = 3) 
) 

Sie müssten die Subselect natürlich mit Ihrer äußeren Abfrage korrelieren.

Verwandte Themen