CASE语句返回多个记录

时间:2020-06-29 12:22:58

标签: sql sql-server

我正在使用以下case语句联接两个表,但是CASE语句当前似乎无法正常工作。我希望它可以将ORDERS表中的REVENUE与BUCKET表中的LIMIT相匹配,并仅返回REVENUE所属的存储区。现在,由于某种原因,它会返回4个带有错误存储桶的行。

在下面的示例数据中,我希望它返回存储桶3。

有人可以帮忙指出这里出了什么问题。 非常感谢。

select o.Org, o.REVENUE,b.BUCKET,
CASE
                       WHEN  o.REVENUE <= b.LIMIT and BUCKET = 'Bucket 1' 
                           THEN '1'
                       WHEN o.REVENUE <= b.LIMIT and BUCKET = 'Bucket 2'  
                           THEN '2'
                       WHEN   0.REVENUE <= b.LIMIT and BUCKET = 'Bucket 3'
                           THEN '3'
                       ELSE '4'
                   END AS DERIVED_BUCKET
from ORDERS o
inner join BUCKET_TABLE b
on o.Org = b.Org
where ID  = '12345'

enter image description here

enter image description here

2 个答案:

答案 0 :(得分:2)

为此使用cross apply

select o.Org, o.REVENUE, b.BUCKET
from ORDERS o cross apply
     (select top (1) b.*
      from bucket_table b
      where  o.Org = b.Org and b.limit >= o.revenue
      order by b.limit desc
     ) b
where ID = '12345';

您还可以使用lag(),以便使用适当的join

select o.*, b.*
from orders o join
     (select b.*, lag(limit) over (partition by org order by limit) as prev_limit
      from buckets b
     ) b
     on b.order = o.org and
        (o.revenue > b.prev_limit or b.prev_limit is null) and
        (o.revenue <= b.limit)

答案 1 :(得分:1)

代码中存在逻辑问题,它将触发所有必须具有下限和上限的大小写语句,因此可以解决问题,例如滞后或超前或表中有范围。

create table ORDERS
(id int,org  varchar(20),REVENUE int)

insert into ORDERS
(id ,org  ,REVENUE )

select 
12345 as id ,'org1'  as org , 1200 REVENUE 


create table BUCKET_TABLE
(org  varchar(20),BUCKET  varchar(20) , limit int )

insert into BUCKET_TABLE
(org  ,BUCKET,limit)

select 
'org1'  as org , 'BUCKET_1' as BUCKET  ,100 as limit
union
select 
'org1'  as org , 'BUCKET_2' as BUCKET  , 1000 limit
union
select 
'org1'  as org , 'BUCKET_3' as BUCKET , 5000 limit 
union
select 
'org1'  as org , 'BUCKET_4' as BUCKET , 10000 limit 

select o.Org, o.REVENUE,b.BUCKET 
,
CASE
                       WHEN ( o.REVENUE < b.LIMIT and 
                       b.BUCKET = 'BUCKET_1' )
                           THEN '1'
                       WHEN   b.rn < o.REVENUE  and  o.REVENUE  <= b.LIMIT and
                        b.BUCKET = 'BBUCKET_2'  THEN '2'
                       WHEN  b.rn < o.REVENUE  and  b.BUCKET = 'BUCKET_3'
                           THEN '3'
                        WHEN  b.rn < o.REVENUE  and  b.BUCKET = 'BUCKET_4'
                           THEN '4'
                   END AS DERIVED_BUCKET
from ORDERS o

inner join 
(select * , LAG(limit) over (partition by org  order by limit asc ) as rn  from BUCKET_TABLE)b
on o.Org = b.Org
where ID  = '12345'

enter image description here