我已经在Excel中接收到数据,并且DATE列(名为ALL_PERIODS)为STRING,其格式为:
JFM 14-W / E 14/05/04
2014年1月,2月,2014年4月4日,周末
我需要将此列划分为三个新列:DATE_(DATE),YEAR_(INT),QUARTER_(INT),因此我编写了以下转换:
DATE列:
ALTER TABLE MY_TABLE
ADD DATE_TEMP VARCHAR2 (128);
UPDATE MY_TABLE
SET DATE_TEMP = SUBSTR(ALL_PERIODS, -2, 2);
UPDATE MY_TABLE
SET DATE_TEMP = REPLACE(DATE_TEMP, '/', '');
UPDATE MY_TABLE
SET DATE_TEMP = to_char(to_date(DATE_TEMP, 'mmddyyyy'), 'yyyy-mm-dd');
UPDATE MY_TABLE
SET DATE_TEMP = REPLACE(DATE_TEMP, '00', '20');
UPDATE MY_TABLE
SET DATE_TEMP = TO_DATE(DATE_TEMP, 'YYYY-MM-DD');
ALTER TABLE MY_TABLE
ADD DATE_ DATE;
UPDATE MY_TABLE
SET DATE_ = DATE_TEMP;
ALTER TABLE MY_TABLE
DROP COLUMN DATE_TEMP;
YEAR列:
ALTER TABLE MY_TABLE
ADD YEAR_TEMP VARCHAR2(128 BYTE);
UPDATE MY_TABLE
SET YEAR_TEMP = SUBSTR(ALL_PERIODS, 8, 4);
ALTER TABLE MY_TABLE
ADD YEAR_ NUMBER(4);
UPDATE MY_TABLE
SET YEAR_ = YEAR_TEMP;
UPDATE MY_TABLE
SET YEAR_ = CONCAT('20', YEAR_);
ALTER TABLE MY_TABLE
DROP COLUMN YEAR_TEMP;
列季度:
ALTER TABLE MY_TABLE
ADD QUARTER NUMBER(1);
UPDATE MY_TABLE
SET QUARTER_ = 4
WHERE DATE_ = '30-DEC-17';
...and the same with other 3 quarters
它以某种方式有效,但是我想它没有效果(我在SQL方面不是很高级,我还在学习),并且更新操作太慢,所以我想转换ALL_PERIODS列,同时将具有三个所需列的数据插入到新表中。
请告诉我,INSERT的外观如何? 谢谢 N
答案 0 :(得分:0)
window.addEventListener('beforeinstallprompt', e => {
console.log('beforeinstallprompt Event fired');
});
答案 1 :(得分:0)
DDL语句(添加/删除列)缓慢且不必要。插入数据时,请勿更改表定义!
我将这样插入3列(用真正的ALL_PERIODS值替换我使用的日期字符串):
INSERT INTO MY_TABLE (DATE_, YEAR_, QUARTER_)
TO_DATE(SUBSTR('JFM 14 - W/E 04/05/14', -8), 'dd/mm/yy'),
EXTRACT(YEAR FROM TO_DATE(SUBSTR('JFM 14 - W/E 04/05/14', -2), 'yy')),
-- OR SHORTER IF ALWAYS IN THE 2000: TO_NUMBER(SUBSTR('JFM 14 - W/E 04/05/14', -2)) + 2000
DECODE(SUBSTR('JFM 14 - W/E 04/05/14',1,3), 'JFM', 1, 'AMJ', 2, 'JAS', 3, 'OND', 4);
致谢
答案 2 :(得分:0)
是否已将ALL_PERIODS加载到表中?
并且要计算的额外列已添加到表中?
然后1次更新就足够了。
UPDATE MY_TABLE
SET
DATE_ = TO_DATE(SUBSTR(RTRIM(ALL_PERIODS),-8),'MM/DD/YY')
,YEAR_ = 2000+SUBSTR(ALL_PERIODS,5,2)
,QUARTER_ = DECODE(SUBSTR(ALL_PERIODS,1,3), 'JFM', 1, 'AMJ', 2, 'JAS', 3, 'OND', 4)
WHERE ALL_PERIODS IS NOT NULL
AND DATE_ IS NULL
在 db <>小提琴here
上进行测试答案 3 :(得分:0)
我首先简单地插入记录来模拟您的Excel日期字符串。您可以使用此逻辑来查看如何完成转换。
设置
INSERT INTO myTable (baseDate) SELECT 'JFM 14 - W/E 04/05/14' FROM dual UNION ALL SELECT 'AMJ 14 - W/E 06/05/14' FROM dual UNION ALL SELECT 'JAS 14 - W/E 09/05/14' FROM dual UNION ALL SELECT 'OND 14 - W/E 12/05/14' FROM dual UNION ALL SELECT 'JFM 15 - W/E 04/05/15' FROM dual UNION ALL SELECT 'AMJ 15 - W/E 06/05/14' FROM dual UNION ALL SELECT 'JAS 15 - W/E 09/05/14' FROM dual UNION ALL SELECT 'JAS 49 - W/E 03/05/49' FROM dual UNION ALL SELECT 'JAS 50 - W/E 04/05/50' FROM dual
下一个SELECT
行将验证服务器的默认日期格式。此值可能会影响字符串的日期解释。
SELECT value FROM v$nls_parameters WHERE parameter ='NLS_DATE_FORMAT';
| VALUE | | :-------- | | DD-MON-RR |
在插入值之后,我可以基于该值更新表。
UPDATE myTable SET DATE_ = TO_DATE( SUBSTR(baseDate,INSTR(baseDate, ' ', -1)+1,8) -- Find last space to get end of string date value. , 'MM/DD/RR' ) /* TO_DATE already creates date object. RR mask rounds to 4-digit year. (49 = 1949, 50 = 2050) */ , QUARTER_ = CASE SUBSTR(baseDate, 1, 3) WHEN 'JFM' THEN 1 WHEN 'AMJ' THEN 2 WHEN 'JAS' THEN 3 WHEN 'OND' THEN 4 END
对于DATE_
,您不需要执行TO_CHAR
,因为TO_DATE
会将字符串转换为数据库中date列的日期值。您的数据库并不真正在乎日期是否看起来像'yyyy-mm-dd',因为它无论如何都不会那样看。我使用RR
掩码将2位数字的年份值转换为4位数字的年份值。这会将49
转换为2049
,将50
转换为1950
。如果您不需要19xx
日期,则可以使用YY
。如果需要,可以对字符串值进行其他验证,以确保可以将其转换为日期。
对于QUARTER_
,这只是一个简单的CASE
语句,用于将四分之一字符串解释为数字。
然后,根据YEAR_
中的日期值更新DATE_
。这样可以确保我的年份在行中保持一致。如果从基本字符串中提取值,也可以在初始更新中完成。
UPDATE myTable SET YEAR_ = EXTRACT ( YEAR FROM DATE_ )
这给我们:
BASEDATE | DATE_ | YEAR_ | QUARTER_ :-------------------- | :-------- | ----: | -------: JFM 14 - W/E 04/05/14 | 05-APR-14 | 2014 | 1 AMJ 14 - W/E 06/05/14 | 05-JUN-14 | 2014 | 2 JAS 14 - W/E 09/05/14 | 05-SEP-14 | 2014 | 3 OND 14 - W/E 12/05/14 | 05-DEC-14 | 2014 | 4 JFM 15 - W/E 04/05/15 | 05-APR-15 | 2015 | 1 AMJ 15 - W/E 06/05/14 | 05-JUN-14 | 2014 | 2 JAS 15 - W/E 09/05/14 | 05-SEP-14 | 2014 | 3 JAS 49 - W/E 03/05/49 | 05-MAR-49 | 2049 | 3 JAS 50 - W/E 04/05/50 | 05-APR-50 | 1950 | 3
由于DATE_
是实际的日期对象,因此在显示时,您可以使用所需的任何蒙版对其进行格式化。
db <>提琴here