繁体   English   中英

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

[英]Avoiding repetitive conditions in the select case and where clause

我有一个表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
P2 char(10) -如果TAB1.PHN_NO2的长度为10并且以5开头,则保持TAB1.PHN_NO2

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


创建表标签2

选择
用户身份,
案例
(LENGTH(TRIM(PHN_NO1))= 10 AND TRIM(PHN_NO1)如'5%')
然后
CAST(TRIM(PHN_NO1)为CHAR(10))
其他
CAST(NULL为CHAR(10))
结束为P1,
情况(LENGTH(TRIM(PHN_NO2))= 10 AND TRIM(PHN_NO2)如'5%')
然后
CAST(TRIM(PHN_NO2)作为CHAR(10))
其他
CAST(NULL为CHAR(10))
结束为P2
哪里
(LENGTH(TRIM(PHN_NO1)= 10 AND TRIM(PHN_NO1)像'5%')
要么
(LENGTH(TRIM(PHN_NO2)= 10 AND TRIM(PHN_NO2)像'5%')

你当然可以! 但是,您必须使用一些条件:

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 Fiddle 示例 。)

这应该适用于任何RDBMS。 需要注意的是,因为你的数据,这是不太可能比你原来了高性能的(这也不会使用索引,给出的TRIM() 鉴于大多数主要的RDBMS都能够按行重复使用确定性函数的结果,因此它也不可能变得更好

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM