2017-03-22 18 views
0

3つのテーブル内に適格フィールド(bool)があります。テーブルは上司、マネージャー、労働者です。階層はBoss - Managers - workersになります。ワーカーはマネージャーを持たないかもしれないし、マネージャーはボスを持たないかもしれない。彼らはすべてこの適格なフィールドを持っています。私は上司が適格なフィールドをtrueに設定しています。マネージャーとマネージャーのすべての従業員はこのプロパティも継承します。ヌルストアドプロシージャではない階層内の最上位テーブルからIDを選択する方法

私は仕事のIDが常に労働者に割り当てられていると言います。最初に、彼がマネージャーと上司を持っているかどうかを調べ、階層内の最高から資格のあるフィールドを取得した後で調べる必要があります。

従業員にマネージャーがいて、マネージャーに上司がいれば、上司の適格フィールドを取得する必要があります。従業員にマネージャーがいるが、マネージャーに割り当てられているボスがない場合は、マネージャーの適格フィールドを取得する必要があります。従業員にマネージャーがいない場合(つまり、自分に割り当てられた上司を雇うことができないという意味)、従業員の資格を取得する必要があります。

私はこれに固執しています。私はSELECT CAST(CASE WHEN B.Id is not null) THEN RETURN..と他のいくつかのバリエーションを試しましたが、運はまだありません。どんな助け?

SELECT W.Id, M.Id, B.Id 
-- CAST(case when ED.Id is not null) THEN return M.Eligible 
from Job J 
Inner Join Worker W on W.Job_Id = J.Id 
Left Join Manager M on M.Id= W.ManagerID 
Left Join Boss B on B.Id = M.BossId 
Where J.Id = 1 and B.Id is not null and M.Id is not null 

は、これまでのところ私はIDのみを取得することができますが、最高ランクの労働者の

例のデータを単に資格Booleanフィールドを返す方法がわからない -

ジョブズ表
- --------
IDが1、ワーカー1、
は、ID 2、ワーカー2、
IDが3、ワーカー3、

人の

労働表
-------------
IDが1、マネージャーID 1、適格偽
IDが2、マネージャーID 2、適格偽
IDが3、マネージャーIDヌル、真適格

マネージャ表
--------------
同上1、BossId 1、適格偽
同上2、BossIdヌル、適格真

ボス表
----------
IDが1、適格真

、それはあまりにも上司を持っている場合INNER JOINと、それが唯一の値を返しますので、私はLEFT JOINを使用する理由。それがtrueに設定されているボスTableまでのすべての道を行くので

ジョブ1が真だろう

それはマネージャーレベルまで上昇し、それが真

に設定されているため、ジョブ2が真のだろうそれは労働者のためにtrueに設定されているため

仕事3は本当だろうし、それが何の上司やマネージャーを持っていないとして、それはその値に

EDITED SQL文を取るだろう

SELECT 
CASE WHEN (B.Id IS NULL) then CASE WHEN (M.Id IS NULL) then W.Id else B.Id END 
from Job J 
Inner Join Worker W on W.Job_Id = J.Id 
Left Join Manager M on M.Id= W.ManagerID 
Left Join Boss B on B.Id = M.BossId 
Where J.Id = 1 and B.Id is not null and M.Id is not null 

明らかにSELECT行が機能していません。この場合、どのようにCASE WHENを実行するか考えていますか?

+0

MySQLまたはMS SQL Serverを使用していますか?関与していない製品にはタグを付けないでください。 – jarlh

+1

なぜLEFT JOINは、これらのテーブルに対してNOT NULL結果が必要なのでしょうか? – jarlh

+1

サンプルテーブルのデータと期待される結果を追加してください。 – jarlh

答えて

0

もうすぐです。 COALESCE関数でこれを行うことができます。この関数は、リストから最初のNULL以外の値を返します。また、LEFT JOININNER JOINに変換するので、B.Idとがnullでない要件を省略する必要があります。

SELECT 
    -- Returns first non-null value, so order by hierarchy 
    COALESCE(B.Eligible, M.Eligible, W.Eligible) AS Eligible 
from Job J 
    Inner Join Worker W on W.Job_Id = J.Id 
    Left Join Manager M on M.Id= W.ManagerID 
    Left Join Boss B on B.Id = M.BossId 
Where J.Id = 1 
+1

ニース、ありがとう。私はちょうど 'CASE WHEN(B.Id IS NULL)と(M.Id IS NULL)それでは複数の' CASE WHEN'ステートメントでそれを行うことができました。それでW.適格 \t WHEN(B.Id IS NULL)適格 \t ELSE B.適格 'あなたの解決策ははるかに優れています –

0

私はこの

select max(ifnull(w.Eligible, false) or ifnull(m.Eligible, false) or ifnull(b.Eligible, false)) as grand_elegible 
from Job J 
Inner join Worker W on W.Job_Id = J.Id 
left join Manager M on M.WorkerId = W.Id 
left join Boss B on B.Id = M.BossId 
where J.Id = 1 
+1

この構文がSQL Serverで動作するかどうかはわかりません。公正であるために、OPは最初にMYSQLをタグ付けしました。 – BJones

+0

thxは私を正当化するためのものです:) MS SQLについてはわかりません - おそらくifnull()の代わりにnvl()が必要ですが、一般的なアイデアは同じでなければなりません – noonex

+0

私はそれが 'ISNULL()'だと思います。また、私は 'MAX()'関数が複数の引数をサポートしているとは思いません。 – BJones

0

タマス、

のようなものに打撃を与えるだろうとしては、上記のタグ与え従っているSQLを知るのは難しいと述べた - 私はのためのMySQLのIFNULLを使用しています例。また、一番下のフィールド名に関する小さな質問です。つまり、これを行う必要があります:

SELECT IFNULL(B.Eligible, IFNULL(M.Eligible, W.Eligible)) 
from Job J 
Inner Join Worker W on W.Job_Id = J.Id 
Left Join Manager M on M.WorkerId = W.Id 
Left Join Boss B on B.Id = M.BossId 
Where J.Id = <JobID> 

主な変更点は選択フィールドです。フィールドの質問:本当にM.WorkerIDですか?私は助け

・ホープ(1はテスト目的のためだったと仮定した場合)パラメータのプレースホルダとしてそこに<JobID>を残した - あなたはW.ManagerIdにM.Idをチェックする(またはそのようないくつかの)する場所それが最終的に になりそうです、 John

+0

申し訳ありません、私はLEFT JOIN'sを混ぜて修正しました –

関連する問題