连接表并将行转换为列,Oracle 11g

时间:2014-01-23 18:32:33

标签: oracle oracle11g

我正在使用Oracle 11g数据库。我必须将多个表连接在一起,其中一个表包含多个测试的结果值,其中每个结果都是一行。当我组合表格时,我想将这些多个测试结果压缩成一行。

以下是我所拥有的简化示例。我正在查询三个表中的数据,这些表称为请购单,测试和特定测试的结果。

SELECT
  requisitions.acc_id
  ,tests.test_name
  ,results.result_numeric
FROM requisitions

inner join req_panels ON requisitions.acc_id = req_panels.acc_id
inner join results ON req_panels.rp_id = results.rp_id
inner join tests ON results.test_id = tests.test_id

WHERE results.test_id IN (1,2,7,8)
ORDER BY requisitions.acc_id

这导致了这个;

Acc_ID | Test_Name | Result_Numeric
------------------------------------
000001 | Test 1    | 24
000001 | Test 2    | 1.5
000002 | Test 1    | 15
000002 | Test 2    | 2.1

但我想得到的是;

Acc_ID | Test 1 | Test 2
--------------------------
000001 |   24   |  1.5
000002 |   15   |  2.1

希望这很清楚。 我是否必须使用枢轴或其他东西?我仍然相对较新,但还未能理解如何使用它们。

感谢。

编辑:这是我使用pivot提出的。我第一次尝试使用数据透视表,如果我做错了什么或者可以更有效地完成某些事情,请告诉我。

SELECT * FROM (
  SELECT requisitions.acc_id
  ,tests.TEST_ID
  ,results.RESULT_NUMERIC
FROM requisitions

inner join req_panels ON requisitions.acc_id = req_panels.acc_id
inner join results ON req_panels.rp_id = results.rp_id
inner join tests ON results.test_id = tests.test_id

WHERE results.TEST_ID IN (1,2,3)
)
pivot(
      MAX(RESULT_NUMERIC)
      for TEST_ID IN ('1' AS Test 1,'2' AS Test 2,'3' AS Test 3)
)
ORDER BY ACC_ID

1 个答案:

答案 0 :(得分:2)

您应该能够通过使用带有CASE表达式的聚合函数来获得最终结果:

SELECT r.acc_id,
  max(case when t.test_name = 'Test 1' then rs.result_numeric end) Test1,
  max(case when t.test_name = 'Test 2' then rs.result_numeric end) Test2
FROM requisitions r
inner join req_panels rp
  ON r.acc_id = rp.acc_id
inner join results rs
  ON rp.rp_id = rs.rp_id
inner join tests t
  ON rs.test_id = t.test_id
WHERE rs.test_id IN (1,2,7,8)
GROUP BY r.acc_id
ORDER BY r.acc_id;

或者您可以使用PIVOT语法:

select acc_id, Test1, Test2
from
(
  select r.acc_id, t.test_name, rs.result_numeric
  FROM requisitions r
  inner join req_panels rp
    ON r.acc_id = rp.acc_id
  inner join results rs
    ON rp.rp_id = rs.rp_id
  inner join tests t
    ON rs.test_id = t.test_id
  WHERE rs.test_id IN (1,2,7,8)
) d
pivot
(
  max(result_numeric)
  for test_name in ('Test 1' as Test1, 'Test 2' as Test2)
) piv;