我正在尝试创建一个SQL视图,它整合了许多单独的选择查询。我在将单个select语句中的子句放入数据库视图时遇到了一些困难。
我的观点的简化版本是:
create or replace view TestView as
select
A.Name,
B.Subscription,
C.Expiry
from
TestTableA as A left outer join TestTableB as B on A.ID = B.A_ID
left outer join TestTableC as C on A.ID = C.A_ID;
我对视图有两个问题:
在frist join上我怎样才能选择Subscription是特定值的记录,如果不是那个值仍然检索Name和Expiry列(在这种情况下,Subscription将为null)?
在第二次加入时,如何指定我只想要具有最近到期日期的记录?
以下是我的测试架构,示例数据和所需的结果集:
create table TestTableA
(
ID int,
Name varchar(32),
Primary Key(ID)
);
create table TestTableB
(
ID int,
A_ID int,
Subscription varchar(32),
Primary Key(ID),
Foreign Key(A_ID) references TestTableA(ID)
);
create table TestTableC
(
ID int,
A_ID int,
Expiry date,
Primary Key(ID),
Foreign Key(A_ID) references TestTableA(ID)
);
create or replace view TestView as
select
A.Name,
B.Subscription,
C.Expiry
from
TestTableA as A left outer join TestTableB as B on A.ID = B.A_ID
left outer join TestTableC as C on A.ID = C.A_ID;
insert into TestTableA values (1, 'Joe');
insert into TestTableB values (1, 1, 'abcd');
insert into TestTableB values (2, 1, 'efgh');
insert into TestTableC values (1, 1, '2012-10-25');
insert into TestTableC values (2, 1, '2012-10-24');
insert into TestTableA values (2, 'Jane');
期望的结果1:
select * from TestView where Subscription is null or Subscription = 'efgh';
Joe, efgh, 2012-10-25
Jane, ,
期望的结果2:
select * from TestView where Subscription is null or Subscription = 'xxxx';
Joe, , 2012-10-25
Jane, ,
答案 0 :(得分:2)
我会用简单的SQL写查询
如果您有SQL Server 2005或更高版本,则可以使用outer apply
而不是使用min()
select
A.Name,
B.Subscription,
C.Expiry
from TestTableA as A
left outer join TestTableB as B on A.ID = B.A_ID and B.Subscription in ('abcd', 'efgh')
left outer join
(
select min(T.Expiry) as Expiry, T.A_ID
from TestTableC as T
group by T.A_ID
) as C on A.ID = C.A_ID
答案 1 :(得分:0)
create or replace view TestView as
select
A.Name,
B.Subscription,
C.Expiry
from
TestTableA as A left outer join TestTableB as B on A.ID = B.A_ID
left outer join TestTableC as C on A.ID = C.A_ID;
where
B.Subscription is not null
and C.Expiry between (now() - interval 1 minute) and now()