避免在select case和where子句中重复条件

时间:2012-08-24 21:06:59

标签: sql select case where-clause repeat

我有一张桌子说TAB1,下面是列 -
USER_ID NUMBER(5),
PHN_NO1 CHAR(20),
PHN_NO2 CHAR(20)

我必须将TAB1中的记录提取到另一个表TAB2中,以便所有记录中包含两个或两个PHN_NO1和PHN_NO2之一的记录的长度为10,并以5开头。 如果在记录中,假设只有PHN_NO1满足条件且PHN_NO2不满足,则TAB2.P1应与TAB1.PHN_NO1相同,但TAB2.P2应为NULL。
如果两者都不满足条件,则不应将记录插入TAB2

TAB2的结构如下 USER_ID号码(5) - 保留从TAB1中选择的记录的ROWID
P1 char(10) - 如果长度为10且以5开头,则保持TAB1.PHN_NO1,否则为NULL P2 char(10) - 如果长度为10,则保持TAB1.PHN_NO2并与5对齐,否则为NULL

我可以编写以下查询来实现上述目的,但CASE和WHERE中的条件是重复的。请建议一种更好地实现上述目标的方法。


  

创建表格2   AS
  SELECT
  USER_ID,
  情况时   (LEARTH(TRIM(PHN_NO1))= 10和TRIM(PHN_NO1)类似'5%')
  THEN
  CAST(TRIM(PHN_NO1)为CHAR(10))
  ELSE
  CAST(NULL为CHAR(10))
  结束为P1,
  案例(长度(TRIM(PHN_NO2))= 10和TRIM(PHN_NO2)类似'5%')
  THEN
  CAST(TRIM(PHN_NO2)为CHAR(10))
  ELSE
  CAST(NULL为CHAR(10))
  结束为P2
  WHERE
  (长度(TRIM(PHN_NO1)= 10和TRIM(PHN_NO1)类似'5%')
  OR
  (长度(TRMI(PHN_NO2)= 10和TRIM(PHN_NO2)类似'5%')

1 个答案:

答案 0 :(得分:1)

当然可以!您必须使用一些条件:

INSERT INTO New_Phone 
        SELECT user_id, phn_no1, phn_no2
        FROM (SELECT user_id,
              CASE WHEN LENGTH(TRIM(phn_no1)) = 10 AND TRIM(phn_no1) like '5%'
                   THEN SUBSTR(phn_no1, 1, 10) ELSE NULL END phn_no1, 
              CASE WHEN LENGTH(TRIM(phn_no2)) = 10 AND TRIM(phn_no2) like '5%'
                   THEN SUBSTR(phn_no2, 1, 10) ELSE NULL END phn_no2
              FROM Old_Phone) Old
        WHERE phn_no1 IS NOT NULL
        OR phn_no2 IS NOT NULL;

(我有一个有效的SQL小提琴example。)

这适用于任何RDBMS。请注意,由于您的数据,这可能不会比您的原始更少高性能(在TRIM()给定的情况下,它不会使用索引)。鉴于大多数主要的RDBMS能够重复使用每行确定性函数的结果,它也不太可能更好

哦,应该注意的是,在国际上,电话号码的长度最多可达15位(国内最低值为6或更低)。也许使用VARCHAR(并为自己节省一些TRIM())? INTEGER(或BIGINT,可能TINYINT)更常用于代理ID,NUMBER有点奇怪。