2011-08-16 18 views
2

シナリオ:ASP.Netアプリケーションの監査員用のレポートを作成する必要があります。私は認可タグのディレクトリ内のweb.configファイルのXMLを解析し、どのユーザーがサイト構造内のどのフォルダにアクセスできるかを提供するレポートを作成するプログラムを持っています。レポートは以下の通りです。SQL Group By条件付き

ユーザー名、ファーストネーム、姓、ディレクトリ、役割、アクセス、 LastLoginDate

enter image description here

問題:GISMOとのレポートからいくつかのディレクトリを見ることができるように(中央の列その中に)2回表示され、ユーザーの許可と拒否の両方が表示されます。ディレクトリを許可する行がある場合、拒否は表示されず、それ以外の場合は結果をグループ化する方法があるかどうかは疑問です。

また、VB.net/C#で操作できる場合は、これもオプションです。それはそこに戻り、Excelスプレッドシートにポンピングされます。

何か助けていただければ幸いです。前もって感謝します。

を編集する必要があります。私はまだディレクトリにユーザーが許可されていないかどうかを示す行を拒否する必要があります。しかし、許可されていれば、拒否行を示すポイントはありません。

+0

は、なぜあなたは追加することはできません。クエリ? – Ramy

+0

私はバックアップする必要があります...あなたのクエリはどのように見えるのですか? – Ramy

+0

@Ramy、私の説明で私が不明だった編集をお読みください。 – Gage

答えて

1

が、これはあなたのパスは、そのような/ディレクトリ/ディレクトリ/、/ディレクトリ/ディレクトリ/などのディレクトリ/ディレクトリ/デフォルトに入っていなかったことを前提としています

リファレンス.aspxなどがあります。あなたが作成した.NETプロセスレベルでデータを解析し、重複を取り除くことが最善の方法です。その段階での解析は通常より簡単です。あなたのコメントに基づいて

select derived.*, 
     case when exists 
     (select top 1 1 from table_name as t2 where t2.username = derived.username and t2.directory=derived.directory and t2.access = 'allow') then 1 else 0 end as is_allowed, 
     case when exists 
     (select top 1 1 from table_name as t2 where t2.username = derived.username and t2.directory=derived.directory and t2.access = 'deny') then 1 else 0 end as is_denied, 
from 
(
select distinct t.username, t.firstname, t.lastname, t.directory 
    from table_name as t 
) as derived 
4

これはOracleデータベース上で動作しますので、SQL Server がCASE操作の主なコンポーネントをサポートしていることを知っています。

CREATE TABLE user_permissions (
    user_role VARCHAR2(10) NOT NULL, 
    dir   VARCHAR2(10) NOT NULL, 
    user_access VARCHAR2(5) NOT NULL 
); 

INSERT INTO user_permissions VALUES ('admin', 'dir1', 'allow'); 
INSERT INTO user_permissions VALUES ('admin', 'dir2', 'allow'); 
INSERT INTO user_permissions VALUES ('power', 'dir1', 'allow'); -- Allow and Deny dir1 
INSERT INTO user_permissions VALUES ('power', 'dir1', 'deny'); 
INSERT INTO user_permissions VALUES ('power', 'dir2', 'deny'); 
COMMIT; 


SELECT UNIQUE j.* 
FROM (
     SELECT user_role, dir, 
       MAX(CASE user_access WHEN 'allow' THEN 1 ELSE 0 END) allowFlag, 
       MAX(CASE user_access WHEN 'deny' THEN 1 ELSE 0 END) denyFlag 
     FROM user_permissions 
     GROUP BY user_role, dir 
    ) t 
JOIN user_permissions j ON (t.user_role = j.user_role AND t.dir = j.dir) 
WHERE j.user_access = 'allow' OR (t.allowFlag = 0 and user_access = 'deny'); 

結果:

USER_ROLE DIR  USER_ACCESS 
---------- ---------- ----------- 
admin  dir1  allow  
admin  dir2  allow  
power  dir1  allow  
power  dir2  deny   

基本的には、ディレクトリの属性を記述した単一の行に複数の行を集約するピボットテーブルを使用します。集計された行を取得したら、宣言した属性を比較して、表示する行を結合するのは簡単です。

+0

SQL Serverでは、UNIQUEは使用できませんが、DISTINCTを使用できます。 –

2

あなたはSQL Server 2005またはそれ以降を持っている場合は、この使用することができます:「グループ」ユニークになるものは何でも入れパーティション句では、

with cte as (
    select ROW_NUMBER() OVER (partition by username, directory order by access) as row, * 
    from report 
) 
select * 
from cte 
where row = 1 

を。このような何かが動作するはず http://msdn.microsoft.com/en-us/library/ms190766.aspx

http://msdn.microsoft.com/en-us/library/ms186734.aspx

+0

万が一「アクセスで注文する」という意味ですか?それはもっと理にかなっていると私は思う。 –

+0

実際、あなたは正しいでしょう、おそらくそうです。かわった。乾杯! –

1
SELECT UserName, Firstname, LastName, Directory, Roles, Access, LastLoginDate 
FROM Report R 
WHERE Access = 'allow' 
    OR (Access = 'deny' 
     AND NOT EXISTS 
     (SELECT * 
      FROM Report R2 
      WHERE R2.Directory = R.Directory 
      AND R2.UserName = R.UserName 
      AND R2.Roles = R.Roles 
     ) 
    ) 

、この行はこれだけ(UserName, Directory)組み合わせがチェックされ、削除する必要があります:あなたに「アクセスは= 『許可』ここで、」

   AND R2.Roles = R.Roles