SQL - 从varchar转换为int并在语句时应用case

时间:2018-03-06 20:53:51

标签: sql data-conversion

我有以下数据元素,我想从中读取最后3位数字,并在SQL中创建另一个CASE表达式和数据类型为INT的列。

DATA -

SCORE
X0450
00350
U0550
!
0650

期望的字段 -

SCORE      SCORE_BUCKET
X0450         300-499
00350         300-499
U0550         500-699
!             Unscorable
0650          500-699

3 个答案:

答案 0 :(得分:0)

在CASE和正则表达式的帮助下,这里有一个选项(Oracle):

SQL> with test (score) as
  2    (select 'X0450' from dual union
  3     select '00350' from dual union
  4     select 'U0550' from dual union
  5     select '!'     from dual union
  6     select '0650'  from dual
  7    )
  8  select score,
  9         case when regexp_like(substr(score, -3), '\d+') then
 10              case when substr(score, -3) between   0 and 299 then '000 - 299'
 11                   when substr(score, -3) between 300 and 499 then '300 - 499'
 12                   when substr(score, -3) between 500 and 699 then '500 - 699'
 13              end
 14              else 'Unscorable'
 15         end score_bucket
 16  from test
 17  order by 2;

SCORE SCORE_BUCK
----- ----------
!     Unscorable
00350 300 - 499
X0450 300 - 499
U0550 500 - 699
0650  500 - 699

SQL>

答案 1 :(得分:0)

使用MS SQL Server:

首先创建一个存储桶表:

CREATE TABLE [dbo].[bucket](
    [score_bucket] [varchar](10) NULL,
    [RangeStart] [int] NULL,
    [RangeEnd] [int] NULL
) 
GO
INSERT [dbo].[bucket] ([score_bucket], [RangeStart], [RangeEnd]) VALUES (N'300-499', 300, 499)
GO
INSERT [dbo].[bucket] ([score_bucket], [RangeStart], [RangeEnd]) VALUES (N'500-699', 500, 699)
GO

然后用空值替换非数字,并对存储桶表执行左连接。

SELECT  S.SCORE
    ,COALESCE(b.score_bucket, 'Unscorable') as SCORE_BUCKET
FROM (  
    SELECT score
           ,CASE
               WHEN  ISNUMERIC(RIGHT(score,3))= 1
               THEN RIGHT(score,3)
               ELSE NULL END AS Val
FROM         dbo.score ) AS S
LEFT JOIN    dbo.bucket AS b ON  Val>= b.RangeStart
                             AND Val <= B.RangeEnd;  

答案 2 :(得分:0)

使用Postgres,您可以使用:

with converted as (
  select score, nullif(regexp_replace(score, '[^0-9]', ''), '')::int as numeric_score
  from the_table
)
select score, numeric_score, 
       case 
          when numeric_score is null then 'Unscorable'
          when numeric_score between 0 and 299 then '000-299'
          when numeric_score between 300 and 499 then '300-499'
          when numeric_score between 500 and 699 then '500-600'
          else ' >= 700'
       end as score_bucket
from converted;

分配&#34;得分桶&#34;如果每个桶的范围存储在单独的表中,则会更容易(更短)。