特定の従業員、その人物の役割に必要なすべての「テスト」を返すクエリを作成しています。その人物はテストを受けていないか、テストの有効期限が切れています。
従業員ロールのすべてのテストをリストした最初の部分は次のとおりです。
SELECT e.EMP_NO, e.POS_CODE, p.PROPERTY_CODE, p.PROPERTY_VALUE
FROM COMPANY_PERS_ASSIGN e
INNER JOIN COMPANY_POS_PROPERTY_ALL p ON p.POS_CODE = e.POS_CODE
WHERE e.EMP_NO = '3615';
ここまでは順調です... この例では、この人物の役割に必要な 4 つのテストがリストされています。
次に、従業員が受けたテストを示すビューに結合する必要があります。
SELECT e.EMP_NO, e.POS_CODE, p.PROPERTY_CODE, p.PROPERTY_VALUE, ep.PROPERTY_CODE, ep.PROPERTY_VALUE
FROM COMPANY_PERS_ASSIGN e
INNER JOIN COMPANY_POS_PROPERTY_ALL p ON p.POS_CODE = e.POS_CODE
LEFT OUTER JOIN COMPANY_EMPLOYEE_PROPERTY_ALL ep ON ep.PROPERTY_VALUE = p.PROPERTY_VALUE
WHERE e.EMP_NO = '3615';
LEFT OUTER JOIN を使用すると、前のクエリからすべての行が返され、追加したばかりのビューから一致する情報があれば返されると思います。
このロールのテストが A/B/C/D で、この従業員がテスト A を 1 回、テスト D を 3 回行った場合、次の出力が期待されます。
3615 POS1 A A A A
3615 POS1 B B
3615 POS1 C C
3615 POS1 D D D D
3615 POS1 D D D D
3615 POS1 D D D D
しかし、代わりに私は得る:
3615 POS1 A A A A
3615 POS1 D D D D
3615 POS1 D D D D
3615 POS1 D D D D
私は PL/SQL よりも T-SQL に精通していますが、私が知る限り、正しいアプローチを取るべきでしたが、明らかに何かが正しくありません。
私は何が欠けていますか?
更新: ロジックに誤りがあることに気付きました。元のコード サンプルでは、COMPANY_EMPLOYEE_PROPERTY_ALL テーブルに結合し、PROPERTY_VALUE (つまりテスト) を介してリンクしましたが、従業員を考慮していませんでした。
これに対処する (そして別のことを試す) ために、サブクエリを導入しました。
SELECT e.EMP_NO, e.POS_CODE, p.PROPERTY_VALUE, p.value_description, ep.PROPERTY_VALUE, ep.value_description, ep.VALID_TO
FROM COMPANY_PERS_ASSIGN e
INNER JOIN COMPANY_POS_PROPERTY_ALL p ON p.POS_CODE = e.POS_CODE
LEFT OUTER JOIN
(Select ep.PROPERTY_VALUE, ep.VALID_TO, ep.value_description
FROM COMPANY_PERS_ASSIGN e
INNER JOIN COMPANY_EMPLOYEE_PROPERTY_ALL ep ON ep.EMP_NO = e.EMP_NO
WHERE e.EMP_NO = '3615') ep on ep.PROPERTY_VALUE = p.PROPERTY_VALUE
WHERE e.EMP_NO = '3615'
AND (to_char(ep.VALID_TO) <= '17-APR-12' OR ep.VALID_To IS NULL);
このソリューションは機能します。
しかし、私が見つけた落とし穴を考えると、元のアプローチをどのように再調整できますか? または、このソリューションに固執する必要があります。私は「作業中」の段階ですが、常にさらなるエレガンス (および学習の機会) を探しています。