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

Sql 避免select case和where子句中的重复条件,sql,select,case,where-clause,repeat,Sql,Select,Case,Where Clause,Repeat,我有一个表,比如TAB1,有以下列- 用户ID号(5), PHN_NO1 CHAR(20), PHN_NO2 CHAR(20) 我必须将TAB1中的记录提取到另一个表TAB2中,这样所有记录的长度都是10,并且从5开始。 如果记录中只有PHN_NO1满足条件,而PHN_NO2不满足条件,则TAB2.P1应与TAB1.PHN_NO1相同,但TAB2.P2应为空。 如果两者都不满足条件,则不应将记录插入TAB2 TAB2的结构如下所示 用户ID号(5)-持有从TAB1中选择的记录的ROWID P1

我有一个表,比如TAB1,有以下列-
用户ID号(5),
PHN_NO1 CHAR(20),
PHN_NO2 CHAR(20)

我必须将TAB1中的记录提取到另一个表TAB2中,这样所有记录的长度都是10,并且从5开始。
如果记录中只有PHN_NO1满足条件,而PHN_NO2不满足条件,则TAB2.P1应与TAB1.PHN_NO1相同,但TAB2.P2应为空。
如果两者都不满足条件,则不应将记录插入TAB2

TAB2的结构如下所示
用户ID号(5)-持有从TAB1中选择的记录的ROWID
P1 char(10)-如果长度为10且以5开头,则保持TAB1.PHN_NO1,否则为空
P2字符(10)-如果长度为10且与5对齐,则保持TAB1.PHN_NO2,否则为空

我可以写下面的查询来实现上面的功能,但是在这种情况下,条件和位置是重复的。请建议一种更好地实现上述目标的方法


创建表TAB2
作为
选择
用户ID,

(长度(修剪(PHN_NO1))=10,修剪(PHN_NO1)如“5%”)
然后
铸造(修剪(PHN_NO1)为字符(10))
否则
强制转换(NULL为字符(10))
以P1结尾,
案例(长度(修剪(PHN_NO2))=10,修剪(PHN_NO2)如“5%”)
然后
铸造(修剪(PHN_NO2)为字符(10))
否则
强制转换(NULL为字符(10))
以P2结尾
其中
(长度(修剪(PHN_NO1)=10,修剪(PHN_NO1)如“5%”)

(长度(修剪(PHN_NO2)=10,修剪(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小提琴。)

这应该适用于任何RDBMS。请注意,由于您的数据,它的性能不可能低于原始数据库(如果使用
TRIM()
,原始数据库将不会使用索引)。鉴于大多数主要RDBMS能够每行重复使用确定性函数的结果,它也不可能更好


哦,应该注意的是,在国际上,电话号码的长度最多可以是15位(在国家/地区,最小长度为6位或更少)。可以使用
VARCHAR
(也可以保存一些
TRIM()
)和
INTEGER
(或者
BIGINT
,或者
TINYINT
)更常用于代理ID,
NUMBER
有点奇怪。

谢谢!这就解决了问题。这只是对我想要实现的目标的一个简单解释,所以电话号码长度实际上对我来说并不重要。非常感谢您的回答:)