0

ここに画像の説明を入力

アプリケーションのデータベースに特定の会社構造を作成し、その構造に基づいて従業員の詳細を調べたいと考えています。問題を以下に示します。

従業員がシステムにログインすると、自分のレベルで働いている従業員の詳細を確認できるはずです。たとえば、「エグゼクティブ B」がシステムにログインすると、スタッフ A、スタッフ B、スタッフ C、およびスタッフ C のサブ スタッフの詳細を確認できるはずです。

同時に、スタッフ C は、セクション ヘッド C にレポートし、セクション ヘッド C は、サブ スタッフではなく、スタッフ C の詳細のみを表示できます。つまり、セクション ヘッド C がログインすると、彼はサブ従業員とスタッフ C を表示できます。

ただし、セクション ヘッド D は、スタッフ C から始まる支店への完全なアクセス権を持っているため、スタッフ C の詳細とそのサブ スタッフの詳細を表示できます。

データベースにこの構造とアクセスレベルを実装し、効率的な方法でそれらをクエリする方法を教えてくれる人はいますか?

4

2 に答える 2

3

この種の階層トラバーサルの問題を解決するための一般的なアプローチは、訪問数と呼ばれる手法を使用することです。これについては、この質問への回答で詳しく説明します。訪問番号を使用すると、階層内の特定のノードの下にあるすべてのノードのリストを簡単に見つけることができます。

従業員テーブルのインボリュートされた外部キーを使用して、各従業員の直属の上司を記録することに注意してください。

あなたの場合、通常のレポート階層の外側に点線のレポート (スタッフ C からセクション ヘッド C まで) もあります。つまり、2 つのアプローチが必要になります。1 つ目は、マネージャーが直属部下と間接部下のすべてを確認できる定期的なレポートに訪問番号を使用し、点線レポートに別のものを使用することです。

点線レポートには 2 種類のルールがあるようです。点線のスーパーバイザーの中には、サブスタッフを見ることができる人もいれば、点線の直属の部下しか見ることができない人もいます。点線のスーパーバイザーが複数いる場合があるため、交差テーブルを追加して、これらの点線の関係を記録する必要があります。この交差テーブルには、点線の監督者が点線のすぐ下の部下のみを表示できるか、またはその人物とそのすべての部下も表示できるかどうかを示すフラグ属性を含めることもできます。

いずれにせよ、点線の関係は従業員とその上司の間で直接記録され、通常の報告関係 (間接的な場合もあります) は訪問番号によって管理されます。

于 2012-08-15T12:12:36.927 に答える
0

従業員にいくつかの自己結合テーブルが必要です。1 つは上司と従業員の関係を表します。2 つ目は、従業員間のピア関係を表します。

これがPostgreSQLのSQLです

stackoverflow カスケードが存在する場合はスキーマを削除します。

スキーマのスタックオーバーフローを作成します。

search_path を stackoverflow、public に設定します。

テーブルの従業員を作成する

(

id serial not null unique,

name text not null unique,

title text not null,

primary key ( id )

);

テーブル レポートの作成

(

supervisorid integer not null references employee ( id )  on delete cascade ,

subordinateid integer not null references employee ( id )
       check ( supervisorid !=  subordinateid ),

unique ( supervisorid, subordinateid ),

unique( subordinateid )

);

テーブル ピアの作成

(

supervisorid integer not null references employee ( id )  on delete cascade ,

peerid integer not null references employee ( id )

       check ( supervisorid != peerid ),

unique ( supervisorid, peerid )

);

直属の部下を次のように作成または置換

 select  supervisor.id  as  "supervisor id", 

        supervisor.name as  "supervisor name",  

  reporting.id as "employee id", reporting.name as  "employee name"

from 

    employee  supervisor, employee reporting , reports

where 

supervisor.id = reports.supervisorid

and reporting.id = reports.subordinateid;






 create or  replace view peerreports as

select * from directreports、peer、employee

   where   

     employee.id = peer.peerid 

       and peer.supervisorid = directreports."supervisor id";

従業員に挿入 (名前、役職)

values ( 'c head', 'c head'), 
       ( 'd head', 'd head'), 
       ('c emp1', 'c emp1' ) , 
       ('c emp2', 'c emp2' ) ;




insert  into reports 

select employee.id as "supervisorid",
        reportsto.id as "subordinateid" 

   from employee,  employee reportsto  

    where employee.name = 'c head'  

   and reportsto.name in ('c emp1',  'c emp2' )

   and  reportsto.name !=  employee.name ;




 insert into peer    

  select employee.id as "supervisorid",  
          peerto.id as "peer.peerid" 

   from employee, employee peerto

      where employee.name = 'c head' and peerto.name = 'd head' 

       and employee.id != peerto.id;

典型的なクエリは次のとおりです

従業員から * を選択します。

レポートから * を選択します。

直属の部下から * を選択します。

ピアから * を選択します。

select * from peerreports, employee where employee.name= 'd head';

于 2012-08-15T12:41:04.693 に答える