ステップバイステップで見ていきましょう...
まず、選択しているエンティティがleave_request
テーブルにあります。それでは、そこから始めましょう。
SELECT leave_request.* FROM leave_request
applied_by
ここで、目的の結果の列のデータを知る必要があります。だからあなたはstaff
テーブルに参加します:
SELECT
applied_staff.name AS applied_by
FROM
leave_request
INNER JOIN staff AS applied_staff ON leave_request.staff_id = applied_staff.staff_id
(テーブル名にエイリアスを使用していることに注意してください。これは後で役立ちます。)
今、あなたはあなたがすでに利用できることを知る必要がapplied_from
あります:applied_to
SELECT
applied_staff.name AS applied_by,
leave_request.applied_from,
leave_request.applied_to
FROM
leave_request
INNER JOIN staff AS applied_staff ON leave_request.staff_id = applied_staff.staff_id
ここで、テーブルにあるapproved_from
とを知る必要があります。approved_to
leave_approval
SELECT
applied_staff.name AS applied_by,
leave_request.applied_from,
leave_request.applied_to,
admin_approval.approved_from,
admin_approval.approved_to
FROM
leave_request
INNER JOIN staff AS applied_staff ON leave_request.staff_id = applied_staff.staff_id
INNER JOIN leave_approval AS admin_approval ON leave_request.request_id = admin_approval.request_id
ええと、今私たちは問題を抱えています。1対多の関係があるため、結果に休暇申請を複製しました。どういうわけかそれをフィルタリングする必要があります。方法を指定しないので、いくつかの仮定を立てます。「管理者」の承認とを知りたいのですが、「管理者」の承認は1つだけです。approved_from
approved_to
これらの仮定をテーブル結合に反映させましょう。
SELECT
applied_staff.name AS applied_by,
leave_request.applied_from,
leave_request.applied_to,
admin_approval.approved_from,
admin_approval.approved_to
FROM
leave_request
INNER JOIN staff AS applied_staff ON leave_request.staff_id = applied_staff.staff_id
INNER JOIN leave_approval AS admin_approval ON leave_request.request_id = admin_approval.request_id
INNER JOIN staff AS approved_staff ON admin_approval.approved_by = approved_staff.staff_id
INNER JOIN group AS approved_staff_group on approved_staff.group_id = approved_staff_group.group_id
WHERE
approved_staff_group.group_name = 'admin'
それは良いはずです。ここでstaff
は、同じクエリで2つの異なる目的のためにテーブルの2つのインスタンスがあるため、テーブルのエイリアシングが便利であることに注意してください。したがって、それらを区別する必要がありました。(私はここで盲目的に飛んでいるので、実際にこれをテストすることはできません。途中で問題が発生した場合は修正してください。MySQLを持っていないため、このコードもフリーハンドで使用しています。便利なので、構文エラーがある場合もお知らせください。)
approved_admin
次に、すでに利用可能な結果にフィールドを追加しましょう。
SELECT
applied_staff.name AS applied_by,
leave_request.applied_from,
leave_request.applied_to,
admin_approval.approved_from,
admin_approval.approved_to,
approved_staff.name AS approved_admin
FROM
leave_request
INNER JOIN staff AS applied_staff ON leave_request.staff_id = applied_staff.staff_id
INNER JOIN leave_approval AS admin_approval ON leave_request.request_id = admin_approval.request_id
INNER JOIN staff AS approved_staff ON admin_approval.approved_by = approved_staff.staff_id
INNER JOIN group AS approved_staff_group on approved_staff.group_id = approved_staff_group.group_id
WHERE
approved_staff_group.group_name = 'admin'
最後に、を知る必要がありapproved_hr
ます。そしてnull
、許可されていますか?次に、これに別の結合を使用します。私も上記と同様の仮定をしています。これを試してみましょう:
SELECT
applied_staff.name AS applied_by,
leave_request.applied_from,
leave_request.applied_to,
admin_approval.approved_from,
admin_approval.approved_to,
approved_staff.name AS approved_admin,
hr_staff.name AS approved_hr
FROM
leave_request
INNER JOIN staff AS applied_staff ON leave_request.staff_id = applied_staff.staff_id
INNER JOIN leave_approval AS admin_approval ON leave_request.request_id = admin_approval.request_id
INNER JOIN staff AS approved_staff ON admin_approval.approved_by = approved_staff.staff_id
INNER JOIN group AS approved_staff_group on approved_staff.group_id = approved_staff_group.group_id
LEFT OUTER JOIN leave_approval AS hr_approval ON leave_request.request_id = hr_approval.request_id
LEFT OUTER JOIN staff AS hr_staff ON hr_approval.approved_by = hr_staff.staff_id
LEFT OUTER JOIN group AS hr_staff_group ON hr_staff.group_id = hr_staff_group.group_id
WHERE
approved_staff_group.group_name = 'admin'
AND hr_staff_group.group_name = 'HR'
私はそれらの後者について完全にLEFT OUTER JOIN
確信していません。最初のものは間違いなくnull
値を許可する結合である必要がありますが、クエリエンジンがそれを超える結合をどのように処理するかはわかりません。私はそれらがINNER JOIN
最初のの範囲内にあることを望みLEFT OUTER JOIN
ます。しかし、それはすべてデータの整合性にも依存していると思いますが、これは保証できません。
"Jack"
値が。の場合に出力として必要であると主張することも注目に値します"jack"
。これを実現するために、このコードでは文字列操作を行いませんでした。値をデータで大文字にする必要がある場合は、データで大文字にします。
繰り返しますが、私はこのコードを保証することはできません。しかし、ウォークスルーとして、それはあなたが正しい方向に動くようになるはずです。質問へのコメントで述べたように、MySQLコードを書くつもりなら、MySQLに関する本を手に入れることを強くお勧めします。
編集:私が与えることができる1つの推奨事項は、データ自体の構造です。具体的には、そのleave_approval
テーブルは少し乱雑に感じられ、混乱を引き起こしているのはそのテーブルだけです。いくつかの推奨事項があります。
- テーブルにを追加
approval_type
しleave_approval
ます。少なくとも、これは、それが管理者の承認、HRの承認、またはその他の種類の承認であるかどうかを示します。(他の種類もありますか?これまでにありますか?)次に、結合された主キー、または少なくとも結合された一意の制約として使用request_id
して、データの整合性を高め、承認の重複を防ぐこともできます。approval_type
- 承認が2種類しかなく、それがおそらく変わらない場合は、両方を
leave_approval
表に反映します。の列を1セット、。の列をadmin_approval_*
1セット用意しhr_approval_*
ます。(各セットにはstaff_id
、承認に関連する日付が含まれます。)次に、それ自体が、と1対1にするためrequest_id
の主キーになる可能性があります。これにより、リレーショナルデータが劇的に簡素化され、基本的にレコードがレコードのオプションの追加情報セットに変わります。結合ははるかに単純になり、データはそれ自体をはるかに明確に表現します。leave_approval
leave_request
leave_approval
leave_request