我有一张桌子说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%')
答案 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
有点奇怪。