SQL:在一个声明中加入人员,培训和解雇培训表?

时间:2014-01-07 20:47:41

标签: sql oracle join

晚上好,

我打赌以前发过类似的问题而且我找不到它。我目前正在努力解决以下问题: 我需要加入一个包含员工的表格和另一个包含员工可预订内部培训的表格,最好使用另一个表格,其中包含已经为每个人培训的培训记录和培训。

样本结构:

table "person"
  -> person_id
  -> last_name
  -> first_name

table "training"
  -> training_id
  -> training_name

table "person2training"
  -> person_ref
  -> training_ref

示例数据:

person: 
  -> person_id: 1, last_name: Muller, first_name: Peter
  -> person_id: 2, last_name: Schmitz, first_name: Horst

training:
  -> training_id: 1, training_name: "Sorting books"
  -> training_id: 2, training_name: "Licking stamps"

person2training:
  -> person_ref: 2, training_ref: 2

期望的结果(垂直连接):

person_id  | training_1    | training_2
-----------|---------------|----------
1          | NULL          | NULL
2          | NULL          | 1 (or true)

表存储在Oracle 11g数据库中,现在我使用PHP中的array_merge()创建“Desired Result”中显示的数据,但我觉得纯SQL解决方案可以在越来越多的员工和培训中表现更好。 / p>

提前致谢!

1 个答案:

答案 0 :(得分:0)

假设OP试图找出所有用户是否都接受过培训1和2。

我认为您不需要所有3个表来获取所需的信息。试试这个

SELECT 
    p.person_id,
    (SELECT 1 FROM person2training pt 
        WHERE p.person_id = pt.person_id AND pt.training_id = 1) [training_1],
    (SELECT 1 FROM person2training pt 
        WHERE p.person_id = pt.person_id AND pt.training_id = 2) [training_2]
FROM person p

您也可以使用LEFT OUTER JOIN获得相同的结果。

 SELECT 
    p.person_id,
    CASE WHEN pt1.person_id IS NOT NULL THEN 1 ELSE NULL END [training_1],
    CASE WHEN pt2.person_id IS NOT NULL THEN 1 ELSE NULL END [training_2]
FROM person p
    LEFT JOIN person2training pt1 ON p.person_id = pt1.person_id AND pt1.training_id = 1
    LEFT JOIN person2training pt2 ON p.person_id = pt2.person_id AND pt2.training_id = 2

编辑:使用PIVOT进行查询,当事先不知道培训时。
使用LEFT OUTER JOIN,因为可能会有人没有经过任何培训。

SELECT *
FROM (SELECT p.person_id, pt.training_ref
      FROM person p
          LEFT OUTER JOIN person_training pt ON p.person_id = pt.person_ref)
PIVOT (COUNT(training_ref) AS trained FOR (training_ref) IN (SELECT training_id 
                                                            FROM training))