0

以下のテーブルがあります

user table
USER_ID    USER_NAME
1          smith
2          clark
3          scott
4          chris
5          john

property table
P_ID    PROPERTY
1       first_name
2       last_name
3       age
4       skill

user_property table
PV_ID    USER_ID    P_ID VALUE
1        1          1    Smith
2        1          2    A
3        1          3    34
4        1          4    Java
5        1          4    DB
6        2          1    Clark
7        2          2    B
8        2          3    39
9        2          4    Java
10       2          4    net
11       2          4    linux
12       3          1    Scott
13       3          2    C
14       3          3    31

以下のように、上記のすべてのテーブルからデータを取得するクエリを作成したいと思います:(利用可能な場合、スキルはそのユーザーの最初のスキルになります。それ以外の場合は null)

USER_ID USER_NAME FIRST_NAME LAST_NAME SKILL
1       smith     Smith      A         Java
2       clark     Clark      B         Java
3       scott     Scott      C         null

私は以下のように試しましたが、パフォーマンスの問題が発生しています:

SELECT
  u.user_id,
  u.user_name,
  MAX(DECODE(p.property, 'first_name', text_value)) firstName,
  MAX(DECODE(p.property, 'last_name', text_value)) lastName,
  MAX(DECODE(p.property, 'age', text_value)) age,
  MAX(DECODE(p.property, 'skill', text_value)) skill
FROM user u,
  property p,
  user_property up,
WHERE u.user_id    = up.user_id
AND p.p_id = up.p_id
GROUP BY u.user_id,
  u.user_name;

これを oracle 11g 用に最適化されたクエリとして記述するにはどうすればよいでしょうか。

4

2 に答える 2

0

以下のクエリを試しましたが、デカルト積を取得しました。

with t as (
select u.user_id, u.user_name, up.p_id, up.value
from user_property up
join user u on u.user_id = up.user_id
where u.user_name = 'smith'
)
select u.user_id, u.user_name,
t_first_name.value first_name,
t_last_name.value last_name,
(select min(value) from t where t.user_id = u.user_id and t.p_id = 4) skill
from user u
left join t t_first_name on t_first_name.user_id = u.user_id and t_first_name.p_id = 1
left join t t_last_name on t_last_name.user_id = u.user_id and t_last_name.p_id = 2;

以下のクエリを実行すると、上記の例で述べたように 5 を取得します (例では、user_id 1 の user_property テーブルに 5 つの行があるため)

select count(u.user_id)
from user_property up
join user u on u.user_id = up.user_id
where u.user_name = 'smith'

したがって、以下のクエリを実行すると、使用テーブルの例に 3 つの行があるため、3 としてカウントされます

with t as (
select u.user_id, u.user_name, up.p_id, up.value
from user_property up
join user u on u.user_id = up.user_id
where u.user_name = 'smith'
)
select count(u.user_id)
from user u
left join t t_first_name on t_first_name.user_id = u.user_id and t_first_name.p_id = 1
left join t t_last_name on t_last_name.user_id = u.user_id and t_last_name.p_id = 2;
于 2014-05-12T09:58:43.133 に答える