以下是帮助您理解我的问题的代码:
create table con ( content_id number);
create table mat ( material_id number, content_id number, resolution number, file_location varchar2(50), file_size number);
create table con_groups (content_group_id number, content_id number);
insert into con values (99);
insert into mat values (1, 99, 7, 'C:\foo.jpg', 1024);
insert into mat values (2, 99, 2, '\\server\xyz.mov', 350000);
insert into mat values (3, 99, 5, '\\server2\xyz.wav', 175000);
insert into con values (100);
insert into mat values (4, 100, 5, 'C:\bar.png', 2048);
insert into mat values (5, 100, 3, '\\server\xyz.mov', 27400);
insert into mat values (6, 100, 7, '\\server2\xyz.wav', 400);
insert into con_groups values (10, 99);
insert into con_groups values (10, 100);
SELECT m.material_id,
m.content_id,
(SELECT max(file_location) keep (dense_rank first order by resolution desc)
FROM mat
WHERE mat.content_id = m.content_id
/* AND ...
AND ...
AND ... */) special_mat_file_location,
(SELECT max(file_size) keep (dense_rank first order by resolution desc)
FROM mat
WHERE mat.content_id = m.content_id
/* AND ...
AND ...
AND ... */) special_mat_file_size
FROM mat m
WHERE m.material_id IN (select material_id
from mat
inner join con on con.content_id = mat.content_id
inner join con_groups on con_groups.content_id = con.content_id
where con_groups.content_group_id = 10);
我把注释的AND强调这是一个简化的例子;我的真实查询中的子查询更复杂,标准更多。
我的问题是:我希望避免重复两个列(file_location and file_size
)的子查询中的所有条件,因为条件完全相同。我很乐意使用公用表表达式(即使用WITH子句进行子查询因子分析)但我不能因为子查询中的“WHERE mat.content_id = m.content_id
”而使其成为相关的子查询。我的理解是,不能使用WITH子句对相关子查询进行因子分析。出于同样的原因,我也不能将此子查询作为内联视图(也就是派生表)放在FROM子句中。
如何包含一次条件并使用相关子查询在结果集中注入多个列?
答案 0 :(得分:2)
使用子查询因子(这就是Oracle所称的 - 它在SQL Server中称为公用表表达式)。支持的9i +:
WITH file AS (
SELECT t.content_id,
MAX(t.file_location) keep (DENSE_RANK t.first ORDER BY t.resolution DESC) 'fileLocation',
MAX(t.file_size) keep (DENSE_RANK t.first ORDER BY t.resolution DESC) 'fileSize'
FROM mat t
GROUP BY t.content_id)
SELECT m.material_id,
m.content_id,
f.fileLocation,
f.fileSize
FROM mat m
JOIN file f ON f.content_id = m.content_id
它旨在用于内联视图重用。您概括了视图,并为JOIN子句中的不同实例定义了特定的过滤。您需要公开要在SELECT子句中加入的列 - 请参阅content_id
作为示例。
相关子查询意味着它可以重写为JOIN - 相关性是JOIN标准。
您可以在Subquery Factoring中定义多个视图 - 如果您提供了更多详细信息,我可以更好地定制答案。
答案 1 :(得分:0)
我想我明白了。我能够抓住“特殊”材料的主键并将主查询包装在另一层中,如下所示:
SELECT x.material_id,
x.content_id,
sp_m.file_location,
sp_m.file_size
FROM (SELECT m.material_id,
m.content_id,
(SELECT max(material_id) keep (dense_rank first order by resolution desc)
FROM mat
WHERE mat.content_id = m.content_id
/* AND ...
AND ...
AND ... */) special_mat_primary_key
FROM mat m
WHERE m.material_id IN (select material_id
from mat
inner join con on con.content_id = mat.content_id
inner join con_groups on con_groups.content_id = con.content_id
where con_groups.content_group_id = 10)) x
LEFT OUTER JOIN mat sp_m ON sp_m.material_id = x.special_mat_primary_key;
让我知道你的想法。