- 已知一个字符类型的日期:2022-01-20,请用SQL显示出此日期对应的下个月的月份,结果要求为Number类型(202201)。
参考答案
sql
SELECT to_date('2022-01-20', 'yyyy-mm-dd') a1,add_months(to_date('2022-01-20', 'yyyy-mm-dd'), 1) a2,to_char(add_months(to_date('2022-01-20', 'yyyy-mm-dd'), 1), 'yyyymm') a3,to_number(to_char(add_months(to_date('2022-01-20', 'yyyy-mm-dd'), 1),'yyyymm')) a4,CAST(to_char(add_months(to_date('2022-01-20', 'yyyy-mm-dd'), 1),'yyyymm') AS NUMBER) a5FROM dual;
- 一个来源表TEMP2_F,数据如下,请用SQL删除表中的重复记录。
ID | CODE |
1 | D1 |
2 | D2 |
1 | D1 |
3 | D2 |
2 | D3 |
2 | D2 |
3 | D1 |
参考答案
sql
CREATE TABLE temp2_f (ID NUMBER(2),CODE VARCHAR2(3));SELECT * FROM temp2_f;
解:
--用rowid找出重复的数据
--找出每个重复数据里最小的那个(在每个重复只有两个的情况才下)
--那如果有个重复有三个怎么办?--groupby所有能输出的值
--用delete表语句删除重复的数据(not in…………)
---删除表数据:DELETE FROM 表名 WHERE 条件;DELETE FROM temp2_fWHERE ROWID NOT IN(SELECT MIN(ROWID) FROM temp2_f f GROUP BY f.id, f.code);
COMMIT;
3.来源表TEMP3_F,字段类型及数据如下:
字段类型 | DATE | VARCHAR2(20) | VARCHAR2(20) | NUMBER |
字段名 | INPUT_DATE | C1 | C2 | AMT |
2021/10/03 | A | P1 | 30 | |
2021/11/04 | B | P1 | 20 | |
2021/10/05 | A | P2 | 50 | |
2021/12/04 | B | P1 | 20 |
根据以上数据,请用SQL按以下要求输出结果,要求在同一个PERIOD_ID中C1 不能重复。
字段类型 | VARCHAR2(20) | NUMBER | NUMBER(38,10) | NUMBER(38,10) |
字段名 | C1 | PERIOD_ID | AMT1 | AMT2 |
规则说明 | C1 | 根据字段INPUT_DATE转换,格式为YYYYMM | 根据C1+PERIOD_ID分组的AMT汇总 | 全表AMT的总计 |
参考答案
sql
--建表:CREATE TABLE temp3_f (input_date DATE,c1 VARCHAR2(20),c2 VARCHAR2(20),amt NUMBER);SELECT * FROM temp3_f;根据以上数据,请用SQL按以下要求输出结果,要求在同一个PERIOD_ID中C1 不能重复。--方法一
SELECT DISTINCT c1,to_number(to_char(input_date, 'yyyymm')) PERIOD_ID,SUM(amt) OVER(PARTITION BY to_number(to_char(input_date, 'yyyymm')), c1) AMT1,SUM(amt) OVER() AMT2FROM temp3_f;--方法二
SELECT c1, PERIOD_ID, MAX(amt1) amt1, MIN(amt2) amt2FROM (SELECT c1,to_number(to_char(input_date, 'yyyymm')) PERIOD_ID,SUM(amt) OVER(PARTITION BY to_number(to_char(input_date, 'yyyymm')), c1) AMT1,SUM(amt) OVER() AMT2FROM temp3_f)GROUP BY c1, PERIOD_ID;
4.来源表 TEMP4_F,字段类型及数据如下:
字段类型 | NUMBER | VARCHAR2(20) | VARCHAR2(20) | NUMBER(38,10) |
字段名 | ID | TYPE | ACC_CODE | AMT |
1 | CR | 1001 | 50 | |
1 | DR | 1002 | 60 | |
2 | CR | 1003 | 80 | |
2 | DR | 9999 | 100 | |
3 | DR | 2005 | 110 | |
4 | CR | 1001 | 30 |
根据以上数据,请用SQL按以下要求输出结果,要求DR的ACC_CODE不为9999。
字段类型 | NUMBER | VARCHAR2(20) | NUMBER(38,10) | VARCHAR2(20) | NUMBER(38,10) |
字段名 | ID | DR_ACC_CODE | DR_AMT | CR_ACC_CODE | CR_AMT |
规则说明 | ID | 源表TYPE为DR对应的ACC_CODE的值 | 源表TYPE为DR对应的AMT的值 | 源表TYPE为CR对应的ACC_CODEE的值 | 源表TYPE为CR对应的AMT的值 |
参考答案
sql
--建表
CREATE TABLE temp4_f (ID NUMBER,TYPE VARCHAR2(20),acc_code VARCHAR2(20),amt NUMBER(38,10));SELECT * FROM temp4_f;根据以上数据,请用SQL按以下要求输出结果,要求DR的ACC_CODE不为9999。
--cr、dr 分别 行转列--根本不用
--再full join--根本不用,而且我耶找不到关联条件
--还要剔除dr acc_code=9999的数据SELECT id,SUM(CASEWHEN TYPE = 'DR' AND acc_code != 9999 THENACC_CODEEND) DR_ACC_CODE,SUM(CASEWHEN TYPE = 'DR' AND acc_code != 9999 THENAMTEND) DR_AMT,SUM(CASEWHEN TYPE = 'CR' THENACC_CODEEND) CR_ACC_CODE,SUM(CASEWHEN TYPE = 'CR' THENAMTEND) CR_AMTFROM temp4_f
---WHERE acc_code!=9999 ---错 GROUP BY ID;
--行转列有时候要groupby 有时候又不要groupby,这是为什么?与sum又什么关系?
5.用sql逻辑实现求中位数 提示:用排名函数
参考答案
sql
--理解中位数
--求emp表中sal的中位数
SELECT MEDIAN(sal) m_sal
FROM emp;--方法一:
SELECT AVG(t2.sal) 中位数FROM (SELECT CASEWHEN MOD(COUNT(1), 2) = 0 THENCOUNT(1) / 2ELSE(COUNT(1) + 1) / 2END lrn,CASEWHEN MOD(COUNT(1), 2) = 0 THENCOUNT(1) / 2 + 1ELSE(COUNT(1) + 1) / 2END rrnFROM emp) t1JOIN (SELECT sal, row_number() OVER(ORDER BY sal) rn FROM emp) t2ON t1.lrn = t2.rnOR t1.rrn = t2.rn;--方法二SELECT AVG(SAL) ZWSFROM (SELECT empno,SAL,ROW_NUMBER() OVER(ORDER BY SAL) R,COUNT(*) OVER() AFROM EMP) ZWHERE R BETWEEN FLOOR((1 + A) / 2) AND CEIL((1 + A) / 2);