0

我有一个表说 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 number(5) - 保存从 TAB1
P1 char(10)中选择的记录的 ROWID - 如果 TAB1.PHN_NO1 的长度为 10 并以 5 开头,则保存 TAB1.PHN_NO1,否则为 NULL
P2 char(10) -如果 TAB1.PHN_NO2 的长度为 10 且为 5,则持有 TAB1.PHN_NO2,否则为 NULL

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


CREATE TABLE TAB2
AS
SELECT
USER_ID,
CASE WHEN
(LENGTH(TRIM(PHN_NO1)) = 10 AND TRIM(PHN_NO1) like '5%')
THEN
CAST(TRIM(PHN_NO1) as CHAR(10))
ELSE
CAST(NULL as CHAR( 10))
END AS P1,
CASE (LENGTH(TRIM(PHN_NO2)) = 10 AND TRIM(PHN_NO2) like '5%')
THEN
CAST(TRIM(PHN_NO2) as CHAR(10))
ELSE
CAST(NULL as CHAR(10 ) ))
END AS P2
WHERE
(LENGTH(TRIM(PHN_NO1) = 10 AND TRIM(PHN_NO1) like '5%')
OR
(LENGTH(TRIM(PHN_NO2) = 10 AND TRIM(PHN_NO2) like '5%')

4

1 回答 1

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

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

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

于 2012-08-24T23:02:45.027 回答