[英]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.