哪里& SQL Server视图中的顶级交互

时间:2012-09-18 16:52:25

标签: sql sql-server tsql where sql-view

您是否知道如何说服SQL Server考虑视图中的WHERE子句? 看起来SQL Server只运行我的视图,评估TOP 1,然后应用"其中id = N"用于过滤视图结果集的子句。 例如:

create table mytable ( id int, name varchar(64) );

insert into mytable values ( 5, 'BOB' );
insert into mytable values ( 5, 'ROBERT' );
insert into mytable values ( 5, 'SMITH, ROBERT' );
insert into mytable values ( 8, 'A.J.' );
insert into mytable values ( 8, 'Al J.' );
insert into mytable values ( 8, 'Albert Johnston' );

select * from mytable;

+----+-----------------+
: id : name            :
+----+-----------------+
:  5 : BOB             :
:  5 : ROBERT          :
:  5 : SMITH, ROBERT   :
:  8 : A.J.            :
:  8 : Al J.           :
:  8 : Albert Johnston :
+----+-----------------+

create view myview as
   select top 1 id, name
   from mytable
   order by len(name) desc

问题:

-- bad, empty result set
-- (I want this to answer 5, 'SMITH, ROBERT')
select * from myview where id = 5 

这些按预期工作:

-- good, answers 8, 'Albert Johnston'
select * from myview

-- good, also answers 8, 'Albert Johnston'
select * from myview where id = 8 

现在没有观点:

-- good, answers 5, 'SMITH, ROBERT'
select top 1 id, name
from mytable
where id = 5
order by len(name) desc

2 个答案:

答案 0 :(得分:1)

在这种情况下,如果你想创建这样的东西,我建议使用一个东西,使用where返回一个值,所以最好创建一个Table-Valued User-Defined Function

Create dbo.YourFunction
(
  @parameter id
)
returns table
as
return select top 1 id, name
   from mytable
   where id = @parameter 
   order by len(name) desc

并像

一样使用它
select * from dbo.yourFunction(5)

答案 1 :(得分:0)

您的视图将始终返回Albert Johnston,因为无法强制它首先评估外部条件。你需要像下面这样的东西,它会给你每个id组的最大长度名称/ Id:

select
    name,
    id
from
(
    select
        name,
        id,
        row_number() OVER (partition by id order by len(name) desc) as [len]
    from 
        theTable
) As tbl1
where [len] = 1