【问题标题】:Can a where clause on a join be used in a view可以在视图中使用连接上的 where 子句吗
【发布时间】:2012-10-07 07:34:25
【问题描述】:

我正在尝试创建一个整合多个单独选择查询的 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;

我的视图有两个问题:

  • 在第一次加入时,我如何才能只选择 Subscription 为特定值的记录,如果不是该值,仍检索 Name 和 Expiry 列(在这种情况下,Subscription 将为空)?

  • 在第二次加入时,如何指定我只想要最近到期日期的记录?

以下是我的测试架构、示例数据和所需的结果集:

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, , 

【问题讨论】:

    标签: sql outer-join sql-view


    【解决方案1】:

    我将使用简单的 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
    

    【讨论】:

      【解决方案2】:
      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() 
      

      【讨论】:

        猜你喜欢
        • 2022-01-23
        • 2017-07-18
        • 2017-05-07
        • 2011-09-23
        • 1970-01-01
        • 2019-11-08
        • 1970-01-01
        • 2012-04-28
        • 1970-01-01
        相关资源
        最近更新 更多