FROM子句中的CASE语句

时间:2013-10-11 20:13:36

标签: sql sql-server

请参阅下面的DDL:

CREATE TABLE dbaddress
(aid integer identity not null, link_id int, link_type char, primary key (aid))
CREATE TABLE dbDoorSupervisor
(did integer identity not null, name varchar(30), primary key (did))
CREATE TABLE dbLicensee
(lid integer identity not null, name varchar(30), primary key (lid))

INSERT INTO dbDoorSupervisor (name) values ('Ian')
INSERT INTO dbLicensee (name) values ('Maria')
INSERT INTO dbaddress (link_id, link_type) values (1,'D')
INSERT INTO dbaddress (link_id, link_type) values (1,'L')

我正在尝试根据提供的Address.AID获取门主管或被许可人的名称。例如,如果在WHERE子句中提供了辅助1,则从门管理程序表返回Ian,但是如果在WHERE子句中提供了辅助2,则从被许可方表返回Maria。

我知道你可以在SELECT子句中使用CASE语句,但你可以在FROM子句中使用它们,即根据提供的AID从地址加入被许可人或地址到门监督吗?

3 个答案:

答案 0 :(得分:4)

您可以像这样切换left outer join部分:

select
    isnull(d.name, l.name) as name
from dbaddress as a
    left outer join dbDoorSupervisor as d on d.did = a.link_id and a.link_type = 'D'
    left outer join dbLicensee as l on l.lid = a.link_id and a.link_type = 'L'

或者仍然加入并切换案例陈述

select
    case a.link_type
        when 'D' then d.name
        when 'L' then l.name
    end as name
from dbaddress as a
    left outer join dbDoorSupervisor as d on d.did = a.link_id
    left outer join dbLicensee as l on l.lid = a.link_id

如果要显示多个列,则可以使用外部应用,这样就不会出现这种情况。必须重复案例:

select
    c.name, c.address, c.second_name
from dbaddress as a
    left outer join dbDoorSupervisor as d on d.did = a.link_id
    left outer join dbLicensee as l on l.lid = a.link_id
    outer apply (
        select d.name, d.second_name, d.address where a.link_type = 'D' union all
        select l.name, l.second_name, l.address where a.link_type = 'L'
    ) as c

答案 1 :(得分:2)

select a.linkd_id,
case when link_type = 'D' then d.name
    when link_type = 'L' then l.name
end as 'Name'
from dbAddress a
left join dbDoorSupervisor d on d.did = a.link_id
left join dbLicensee l on l.lid = a.link_id

答案 2 :(得分:0)

不是没有动态SQL,它有自己的一组问题。

如果您的数据库很简单,只有2种左右的可能性,一种简单的方法是连接两者并手动处理结果,如:

select
    a.aid
    ,case a.link_type
        when 'D' then ds.name
        when 'L' then l.name
    end [name]
from
    dbaddress a
left join
    dbDoorSupervisor ds on a.link_type = 'D' and a.link_id = ds.did
left join
    dbLicensee l on a.link_type = 'L' and a.link_id = l.lid