SQL Pivot示例

时间:2017-11-12 12:53:22

标签: sql oracle11g pivot

EAV模型

create table people_details
( id number
, name varchar2(30)
, det_number number
, det_text varchar2(30)
, prop_id number
);

create table properties
( id number
, description varchar2(30)
);

insert into properties values (1,'EYE COLOR');
insert into properties values (2,'INCOME');
insert into properties values (3,'EDUCATION');

INSERT INTO people_details VALUES (1,'JOHN',NULL,'BLUE',1);
INSERT INTO people_details VALUES (2,'JOHN',5000,NULL,2);
INSERT INTO people_details VALUES (3,'JOHN',NULL,'HIGHSCHOOL',3);
INSERT INTO people_details VALUES (4,'PHILIP',NULL,'GREEN',1);
INSERT INTO people_details VALUES (5,'PHILIP',7000,NULL,2);
INSERT INTO people_details VALUES (6,'PHILIP',NULL,'COLLEGE',3);
INSERT INTO people_details VALUES (7,'SANDY',NULL,'BROWN',1);
INSERT INTO people_details VALUES (8,'SANDY',9000,NULL,2);
INSERT INTO people_details VALUES (9,'SANDY',NULL,'COLLEGE',3);

现在选择所有蓝眼睛或收入高于平均水平的人。 这就是我所做的

WITH PEOPLE AS (
  SELECT * FROM(
    SELECT NAME, DESCRIPTION, NVL(DET_TEXT, TO_CHAR(DET_NUMBER)) AS DETAIL
    FROM PEOPLE_DETAILS PPL
    JOIN PROPERTIES PRO ON PPL.PROP_ID = PRO.ID
  )
  PIVOT (
    MAX(DETAIL)
    FOR DESCRIPTION IN ('EYE COLOR' as EYE_COLOR, 'EDUCATION' AS EDUCATION, 'INCOME' AS INCOME)
  )
)
SELECT * FROM PEOPLE WHERE EYE_COLOR = 'BLUE'
UNION
SELECT * FROM PEOPLE WHERE INCOME > (SELECT AVG(INCOME) FROM PEOPLE);

有没有更好的方法呢?在这里我将收入转换为字符,avg函数可能会进行隐式转换。不确定它是否适用于程序。 你会如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

我会使用group byhaving解决此问题:

with p as (
      select pd.name,
             max(case when p.description = 'EYE COLOR' then det_text end) as eye_color,
             max(case when p.description = 'INCOME' then cast(det_text as number) end) as income,
             max(case when p.description = 'EDUCATION' then det_text end) as education
      from people_details pd join
           properties p
           on pd.prop_id = p.id
      group by pd.name
     )
select p.*
from (select p.*, avg(income) over () as avg_income
      from p
     ) p
where income > avg_income or eye_color = 'BLUE';

此方法的一个优点是,您可以在计算时立即将income表示为数字。