Sybase - 如何从SQL中的条件返回第一个值?

时间:2017-11-14 17:46:57

标签: sybase-ase

假设我正在尝试返回一些表格中的列与我设​​置的条件相匹配的结果。但我只想从条件中的可能值列表中返回第一个结果。有没有快速简便的方法呢?我想我可以以某种方式使用合并,但不知道如何构建它。

类似的东西:

select identifier,purpose from table
where identifier = 'letters'
and purpose = coalesce('A','B','C')
group by purpose

所以在表格中,如果没有目的,那么我只希望出现B目的。如果它不存在,那么我希望C出现,如果它们都不存在,那么理想情况下我会想要返回null或没有结果。我宁愿不做几个case语句,其中如果A为null然后查看B,那么如果B为null则查找C.是否有语法快速的方法来执行此操作?

编辑:如果我列出了多个标识符,我也希望这个可以工作,例如:

select identifier,purpose from table
where identifier in ('letters1', 'letters2')
and purpose = coalesce('A','B','C')
group by purpose

我返回两个结果(如果它们存在) - 每个标识符有一个目的,其目的按照A的重要性顺序排列,然后是B,然后是C,如果不存在则为null。

不幸的是,我对caolesce的推理在上面没有用,因为没有变量是null,所以我的查询只会尝试返回'A'的所有目的而没有我想要查询的回退。我想尽可能避免使用临时表。

1 个答案:

答案 0 :(得分:1)

Sybase ASE不支持row_number()函数(否则这将非常简单),因此一个选项是使用#temp表来模拟(在某种程度上)row_number()功能

一些示例数据:

create table mytab
(identifier     varchar(30)
,purpose        varchar(30)
)
go

insert mytab values ('letters1','A')
insert mytab values ('letters1','B')
insert mytab values ('letters1','C')

insert mytab values ('letters2','A')
insert mytab values ('letters2','B')
insert mytab values ('letters2','C')
go

使用标识列和第2列创建#temp表,以保存您希望优先排序的项目;优先级由行插入#temp表的顺序决定。

create table #priority
(id        smallint    identity
,purpose   varchar(30))
go

insert #priority (purpose)
select 'A'                  -- first  priority
union all
select 'B'                  -- second priority
union all
select 'C'                  -- last   priority
go

select * from #priority order by id
go

 id     purpose
 ------ -------
      1 A
      2 B
      3 C

我们将使用派生表来查找最高优先级purpose(即最小id值)。然后,我们将此最小id加入#priority以生成最终结果集:

select  dt.identifier,
        p.purpose

from    (-- join mytab with #priority, keeping only the minimal priority id of the rows that exist:

         select m.identifier,
                min(p.id)       as min_id

         from   mytab m

         join   #priority p
         on     p.purpose = m.purpose

         group by m.identifier) dt

-- join back to #priority to convert min(id) into the actual purpose:

join    #priority p
on      p.id = dt.min_id

order by 1
go

使用不同的mytab数据集进行一些测试:

/* contents of mytab:

insert mytab values ('letters1','A')
insert mytab values ('letters1','B')
insert mytab values ('letters1','C')

insert mytab values ('letters2','A')
insert mytab values ('letters2','B')
insert mytab values ('letters2','C')
*/

 identifier purpose
 ---------- -------
 letters1         A
 letters2         A

/* contents of mytab:

--insert mytab values ('letters1','A')
--insert mytab values ('letters1','B')
insert mytab values ('letters1','C')

--insert mytab values ('letters2','A')
insert mytab values ('letters2','B')
insert mytab values ('letters2','C')
*/

 identifier purpose
 ---------- -------
 letters1         C
 letters2         B

如果一行不存在则返回NULL并不容易,因为生成NULL需要存在一行......某处......与{{1}相关联}。

一个想法是通过创建另一个#temp表(例如,NULL)来扩展#temp表的想法,其中包含您要搜索的所需#identifiers值列表。然后,您可以使用identifierleft (outer) join的{​​{1}},以确保始终为每个#identifiers生成结果记录。