ORACLE查询
2016-04-09 17:29
399 查看
使用函数提高查询效率
create table STUDENT
(
STUNO NUMBER not null,
STUNAME VARCHAR2(1000),
SCORE NUMBER,
constraint PK_STUDENT primary key (STUNO)
);
-- Add comments to the columns
comment on column STUDENT.STUNO
is '学号';
comment on column STUDENT.STUNAME
is '姓名';
comment on column STUDENT.SCORE
is '成绩';
insert into STUDENT (STUNO, STUNAME, SCORE)
values (1, '张三', 78);
insert into STUDENT (STUNO, STUNAME, SCORE)
values (2, '李四', 92);
insert into STUDENT (STUNO, STUNAME, SCORE)
values (3, '王五', 67);
insert into STUDENT (STUNO, STUNAME, SCORE)
values (4, '赵六', 88);
1.使用集合(低效)
SELECT STUNAME, SCORE, '优'
FROM STUDENT
WHERE SCORE >= 90
UNION ALL
SELECT STUNAME, SCORE, '良'
FROM STUDENT
WHERE SCORE >= 80
AND SCORE < 90
UNION ALL
SELECT STUNAME, SCORE, '中'
FROM STUDENT
WHERE SCORE >= 60
AND SCORE < 80
UNION ALL
SELECT STUNAME, SCORE, '差' FROM STUDENT WHERE SCORE < 60;
SQL> SELECT STUNAME, SCORE, '优'
2 FROM STUDENT
3 WHERE SCORE >= 90
4 UNION ALL
5 SELECT STUNAME, SCORE, '良'
6 FROM STUDENT
7 WHERE SCORE >= 80
8 AND SCORE < 90
9 UNION ALL
10 SELECT STUNAME, SCORE, '中'
11 FROM STUDENT
12 WHERE SCORE >= 60
13 AND SCORE < 80
14 UNION ALL
15 SELECT STUNAME, SCORE, '差' FROM STUDENT WHERE SCORE < 60;
STUNAME SCORE '
-------------------- ---------- --
李四 92 优
赵六 88 良
张三 78 中
王五 67 中
2.使用decode函数(高效) sign() 大于0返回1 小于0返回-1 等于0 返回0
--- sign()如果是-1表示不嵌套,0表示嵌套,decode最后一层else表示等级,以此类推,直到计算到socre-60这一级
SELECT STUNAME,
SCORE,
decode(sign(score - 90),
-1,
decode(sign(score - 80),
-1,
decode(sign(score - 60), -1, '差', '中'),
'良'),
'优')
FROM STUDENT;
SQL> SELECT STUNAME,
2 SCORE,
3 DECODE(SIGN(SCORE - 90),
4 -1,
5 DECODE(SIGN(SCORE - 80),
6 -1,
7 DECODE(SIGN(SCORE - 60), -1, '差', '中'),
8 '良'),
9 '优')
10 FROM STUDENT;
STUNAME SCORE DE
-------------------- ---------- --
张三 78 中
李四 92 优
王五 67 中
赵六 88 良<pre class="sql" name="code">DROP TABLE RESULT;
create table RESULT(rq VARCHAR2(10),SHENGFU VARCHAR2(2));
insert into result values('2005-05-09','胜');
insert into result values('2005-05-09','胜');
insert into result values('2005-05-09','负');
insert into result values('2005-05-09','负');
insert into result values('2005-05-10','胜');
insert into result values('2005-05-10','负');
insert into result values('2005-05-10','负');
COMMIT;
如果要生成下列结果, 该如何写sql语句?
胜 负
2005-05-09 2 2
2005-05-10 1 2
解答:
a,第一种方式
1.根据RQ进行group by 操作,即根据时间进行分组,
2.再求出同一时间胜和负的合计值
SELECT RQ,
SUM(CASE
WHEN SHENGFU = '胜' THEN
1
ELSE
0
END) 胜,
SUM(CASE
WHEN SHENGFU = '负' THEN
1
ELSE
0
END) 负
FROM RESULT
GROUP BY RQ;
SQL> SELECT RQ,
2 SUM(CASE
3 WHEN SHENGFU = '胜' THEN
4 1
5 ELSE
6 0
7 END) 胜,
8 SUM(CASE
9 WHEN SHENGFU = '负' THEN
10 1
11 ELSE
12 0
13 END) 负
14 FROM RESULT
15 GROUP BY RQ;
RQ 胜 负
---------- ---------- ----------
2005-05-10 1 2
2005-05-09 2 2
b.第二种方式
1.分别查询胜的次数及其时间,
2.再把两个结果集进行内连接
SELECT N.RQ, N.胜, M.负
FROM (SELECT RQ, COUNT(*) AS 胜
FROM RESULT
WHERE SHENGFU = '胜'
GROUP BY RQ) N
INNER JOIN (SELECT RQ, COUNT(*) AS 负
FROM RESULT
WHERE SHENGFU = '负'
GROUP BY RQ) M ON N.RQ = M.RQ;
SQL> SELECT N.RQ, N.胜, M.负
2 FROM (SELECT RQ, COUNT(*) AS 胜
3 FROM RESULT
4 WHERE SHENGFU = '胜'
5 GROUP BY RQ) N
6 INNER JOIN (SELECT RQ, COUNT(*) AS 负
7 FROM RESULT
8 WHERE SHENGFU = '负'
9 GROUP BY RQ) M ON N.RQ = M.RQ;
RQ 胜 负
---------- ---------- ----------
2005-05-10 1 2
2005-05-09 2 2
c.第三种方式
1.分别查询胜的次数及其时间
2、通过等值条件进行连接起来
SELECT N.RQ, N.胜, M.负
FROM (SELECT RQ, COUNT(*) AS 胜
FROM RESULT
WHERE SHENGFU = '胜'
GROUP BY RQ) N, (SELECT RQ, COUNT(*) AS 负
FROM RESULT
WHERE SHENGFU = '负'
GROUP BY RQ) M
WHERE N.RQ = M.RQ;
SQL> SELECT N.RQ, N.胜, M.负
2 FROM (SELECT RQ, COUNT(*) AS 胜
3 FROM RESULT
4 WHERE SHENGFU = '胜'
5 GROUP BY RQ) N, (SELECT RQ, COUNT(*) AS 负
6 FROM RESULT
7 WHERE SHENGFU = '负'
8 GROUP BY RQ) M
9 WHERE N.RQ = M.RQ;
RQ 胜 负
---------- ---------- ----------
2005-05-10 1 2
2005-05-09 2 2<pre class="sql" name="code">怎么把这样一个表儿
year month amount
1991 1 1.1
1991 2 1.2
1991 3 1.3
1991 4 1.4
1992 1 2.1
1992 2 2.2
1992 3 2.3
1992 4 2.4
查成这样一个结果
year m1 m2 m3 m4
1991 1.1 1.2 1.3 1.4
1992 2.1 2.2 2.3 2.4
create table AMOUNT
(
YEAR VARCHAR2(4),
MONTH VARCHAR2(2),
AMOUNT NUMBER(15,2)
);
insert into amount (YEAR, MONTH, AMOUNT)
values ('1991', '1', 1.10);
insert into amount (YEAR, MONTH, AMOUNT)
values ('1991', '2', 1.20);
insert into amount (YEAR, MONTH, AMOUNT)
values ('1991', '3', 1.30);
insert into amount (YEAR, MONTH, AMOUNT)
values ('1991', '4', 1.40);
insert into amount (YEAR, MONTH, AMOUNT)
values ('1992', '1', 2.10);
insert into amount (YEAR, MONTH, AMOUNT)
values ('1992', '2', 2.20);
insert into amount (YEAR, MONTH, AMOUNT)
values ('1992', '3', 2.30);
insert into amount (YEAR, MONTH, AMOUNT)
values ('1992', '4', 2.40);
思路:group by year统计年,再条件判断每个月,统计所在月,所在月的合计值显示出来select year,
(select sum(amount)
from amount m
where month = 1
and m.year = amount.year) as m1,
(select sum(amount)
from amount m
where month = 2
and m.year = amount.year) as m2,
(select sum(amount)
from amount m
where month = 3
and m.year = amount.year) as m3,
(select sum(amount)
from amount m
where month = 4
and m.year = amount.year) as m4
from amount
group by year;
SQL> select year,
2 (select sum(amount)
3 from amount m
4 where month = 1
5 and m.year = amount.year) as m1,
6 (select sum(amount)
7 from amount m
8 where month = 2
9 and m.year = amount.year) as m2,
10 (select sum(amount)
11 from amount m
12 where month = 3
13 and m.year = amount.year) as m3,
14 (select sum(amount)
15 from amount m
16 where month = 4
17 and m.year = amount.year) as m4
18 from amount
19 group by year;
YEAR M1 M2 M3 M4
---- ---------- ---------- ---------- ----------
1991 1.1 1.2 1.3 1.4
1992 2.1 2.2 2.3 2.4<pre class="sql" name="code">查询员工服务的年限
SELECT ENAME,
TRUNC(MONTHS_BETWEEN(SYSDATE, HIREDATE) / 12) YEAR,
TRUNC(MOD(MONTHS_BETWEEN(SYSDATE, HIREDATE), 12)) MONTH,
TRUNC(MOD(SYSDATE - HIREDATE, 30)) DAY
FROM EMP;
SQL> SELECT ENAME,
2 TRUNC(MONTHS_BETWEEN(SYSDATE, HIREDATE) / 12) YEAR,
3 TRUNC(MOD(MONTHS_BETWEEN(SYSDATE, HIREDATE), 12)) MONT
4 TRUNC(MOD(SYSDATE - HIREDATE, 30)) DAY
5 FROM EMP;
ENAME YEAR MONTH DAY
---------- ---------- ---------- ----------
SMITH 34 7 13
ALLEN 34 5 8
WARD 34 5 6
JONES 34 3 27
MARTIN 33 10 28
BLAKE 34 2 28
CLARK 34 1 19
SCOTT 28 3 9
KING 33 8 8
TURNER 33 10 18
ADAMS 28 2 5
ENAME YEAR MONTH DAY
---------- ---------- ---------- ----------
JAMES 33 7 22
FORD 33 7 22
MILLER 33 6 1
已选择14行。<pre class="sql" name="code">统计每年入职的员工个数,效果如下:
TOTAL 1980 1981 1982 1987 1990
-------- ---------- ---------- ---------- ---------- ----------
14 1 10 1 2 0
方式一:
思路:
通过group by 入职日期的年份来获取,适用统计所有年份的入职人数
select to_char(hiredate, 'yyyy') AS 年份, count(*)
from emp
group by to_char(hiredate, 'yyyy')
order by 1
SQL>
1 select to_char(hiredate, 'yyyy') AS 年份, count(*)
2 from emp
3 group by to_char(hiredate, 'yyyy')
4* order by 1
SQL> /
年份 COUNT(*)
---- ----------
1980 1
1981 10
1982 1
1987 2
方式二:
显示总数,并按条件求每年的入职人数(繁锁,但显示直观,适用统计特定年份的人数,查询次数多)
select (select count(*) from emp) total,
(select count(*) from emp where to_char(hiredate, 'yyyy') = '1980') "1980",
(select count(*) from emp where to_char(hiredate, 'yyyy') = '1981') "1981",
(select count(*) from emp where to_char(hiredate, 'yyyy') = '1982') "1982",
(select count(*) from emp where to_char(hiredate, 'yyyy') = '1987') "1987",
(select count(*) from emp where to_char(hiredate, 'yyyy') = '1990') "1990"
from emp
where rownum = 1
1 select
2 (select count(*) from emp) total,
3 (select count(*) from emp where to_char(hiredate, 'yyyy')='1980') "1980",
4 (select count(*) from emp where to_char(hiredate, 'yyyy')='1981') "1981",
5 (select count(*) from emp where to_char(hiredate, 'yyyy')='1982') "1982",
6 (select count(*) from emp where to_char(hiredate, 'yyyy')='1987') "1987",
7 (select count(*) from emp where to_char(hiredate, 'yyyy')='1990') "1990"
8 from
9 emp
10 where
11* rownum=1
SQL> /
TOTAL 1980 1981 1982 1987 1990
---------- ---------- ---------- ---------- ---------- ----------
14 1 10 1 2 0
方法三:
思路:
和方法二显示的效果相同 ,但是比第二种方法优,通过函数判断,减少查询次数
select count(*) total,
sum(Decode(to_char(hiredate, 'yyyy'), '1980', 1, 0)) "1980",
sum(Decode(to_char(hiredate, 'yyyy'), '1981', 1, 0)) "1981",
sum(Decode(to_char(hiredate, 'yyyy'), '1982', 1, 0)) "1982",
sum(Decode(to_char(hiredate, 'yyyy'), '1987', 1, 0)) "1987",
sum(Decode(to_char(hiredate, 'yyyy'), '1990', 1, 0)) "1990"
from emp
1 select
2 count(*) total,
3 sum(Decode(to_char(hiredate, 'yyyy'), '1980', 1, 0)) "1980",
4 sum(Decode(to_char(hiredate, 'yyyy'), '1981', 1, 0)) "1981",
5 sum(Decode(to_char(hiredate, 'yyyy'), '1982', 1, 0)) "1982",
6 sum(Decode(to_char(hiredate, 'yyyy'), '1987', 1, 0)) "1987",
7 sum(Decode(to_char(hiredate, 'yyyy'), '1990', 1, 0)) "1990"
8 from
9* emp
SQL> /
TOTAL 1980 1981 1982 1987 1990
---------- ---------- ---------- ---------- ---------- ----------
14 1 10 1 2 0
获取当前时间,显示为 xxxx年xx月xx日 xx时xx分xx秒 的格式
SQL(使用双引号向日期格式中添加字符):
select to_char(sysdate, 'yyyy"年"mm"月"dd"日" hh"时"mi"分"ss"秒"') from dual;
结果:
TO_CHAR(SYSDATE,'YYYY"年"MM
---------------------------
2012年03月08日 01时04分01秒
假如数据量很大约1000万条,写一个你认为最高效的SQL,用一个SQL计算以下四种人
sal>9999 and age>35
sal>9999 and age<35
sal<9999 and age>35
sal<9999 and age>35
case when方式
select sum(case
when sal > 9999 and
TRUNC(MONTHS_BETWEEN(SYSDATE, HIREDATE) / 12) > 35 then
1
else
0
end) A,
sum(case
when sal > 9999 and
TRUNC(MONTHS_BETWEEN(SYSDATE, HIREDATE) / 12) < 35 then
1
else
0
end) B,
sum(case
when sal < 9999 and
TRUNC(MONTHS_BETWEEN(SYSDATE, HIREDATE) / 12) > 35 then
1
else
0
end) C,
sum(case
when sal < 9999 and
TRUNC(MONTHS_BETWEEN(SYSDATE, HIREDATE) / 12) < 35 then
1
else
0
end) D
from emp;
SQL> select sum(case
2 when sal > 9999 and
3 TRUNC(MONTHS_BETWEEN(SYSDATE, HIREDATE) / 12) > 35 then
4 1
5 else
6 0
7 end) A,
8 sum(case
9 when sal > 9999 and
10 TRUNC(MONTHS_BETWEEN(SYSDATE, HIREDATE) / 12) < 35 then
11 1
12 else
13 0
14 end) B,
15 sum(case
16 when sal < 9999 and
17 TRUNC(MONTHS_BETWEEN(SYSDATE, HIREDATE) / 12) > 35 then
18 1
19 else
20 0
21 end) C,
22 sum(case
23 when sal < 9999 and
24 TRUNC(MONTHS_BETWEEN(SYSDATE, HIREDATE) / 12) < 35 then
25 1
26 else
27 0
28 end) D
29 from emp;
A B C D
---------- ---------- ---------- ----------
0 0 0 17
Oracle层级查询
--层次化查询,注意prior是Oracle内置的操作符,仅用来处理层次化查询
select level,
lpad(' ', 2 * (level - 1)) || last_name "EmpName",
employee_id,
manager_id,
first_name,
last_name,
hire_date
from employees
--表示根节点为manager_id
start with manager_id is null
--prior表示父行的employee_id,等于当前行的manager_id
connect by manager_id = prior employee_id
order by level;
</listener>
说明:本人于ITEYE创建于2013年,现转移到CSDN
</listener>
create table STUDENT
(
STUNO NUMBER not null,
STUNAME VARCHAR2(1000),
SCORE NUMBER,
constraint PK_STUDENT primary key (STUNO)
);
-- Add comments to the columns
comment on column STUDENT.STUNO
is '学号';
comment on column STUDENT.STUNAME
is '姓名';
comment on column STUDENT.SCORE
is '成绩';
insert into STUDENT (STUNO, STUNAME, SCORE)
values (1, '张三', 78);
insert into STUDENT (STUNO, STUNAME, SCORE)
values (2, '李四', 92);
insert into STUDENT (STUNO, STUNAME, SCORE)
values (3, '王五', 67);
insert into STUDENT (STUNO, STUNAME, SCORE)
values (4, '赵六', 88);
1.使用集合(低效)
SELECT STUNAME, SCORE, '优'
FROM STUDENT
WHERE SCORE >= 90
UNION ALL
SELECT STUNAME, SCORE, '良'
FROM STUDENT
WHERE SCORE >= 80
AND SCORE < 90
UNION ALL
SELECT STUNAME, SCORE, '中'
FROM STUDENT
WHERE SCORE >= 60
AND SCORE < 80
UNION ALL
SELECT STUNAME, SCORE, '差' FROM STUDENT WHERE SCORE < 60;
SQL> SELECT STUNAME, SCORE, '优'
2 FROM STUDENT
3 WHERE SCORE >= 90
4 UNION ALL
5 SELECT STUNAME, SCORE, '良'
6 FROM STUDENT
7 WHERE SCORE >= 80
8 AND SCORE < 90
9 UNION ALL
10 SELECT STUNAME, SCORE, '中'
11 FROM STUDENT
12 WHERE SCORE >= 60
13 AND SCORE < 80
14 UNION ALL
15 SELECT STUNAME, SCORE, '差' FROM STUDENT WHERE SCORE < 60;
STUNAME SCORE '
-------------------- ---------- --
李四 92 优
赵六 88 良
张三 78 中
王五 67 中
2.使用decode函数(高效) sign() 大于0返回1 小于0返回-1 等于0 返回0
--- sign()如果是-1表示不嵌套,0表示嵌套,decode最后一层else表示等级,以此类推,直到计算到socre-60这一级
SELECT STUNAME,
SCORE,
decode(sign(score - 90),
-1,
decode(sign(score - 80),
-1,
decode(sign(score - 60), -1, '差', '中'),
'良'),
'优')
FROM STUDENT;
SQL> SELECT STUNAME,
2 SCORE,
3 DECODE(SIGN(SCORE - 90),
4 -1,
5 DECODE(SIGN(SCORE - 80),
6 -1,
7 DECODE(SIGN(SCORE - 60), -1, '差', '中'),
8 '良'),
9 '优')
10 FROM STUDENT;
STUNAME SCORE DE
-------------------- ---------- --
张三 78 中
李四 92 优
王五 67 中
赵六 88 良<pre class="sql" name="code">DROP TABLE RESULT;
create table RESULT(rq VARCHAR2(10),SHENGFU VARCHAR2(2));
insert into result values('2005-05-09','胜');
insert into result values('2005-05-09','胜');
insert into result values('2005-05-09','负');
insert into result values('2005-05-09','负');
insert into result values('2005-05-10','胜');
insert into result values('2005-05-10','负');
insert into result values('2005-05-10','负');
COMMIT;
如果要生成下列结果, 该如何写sql语句?
胜 负
2005-05-09 2 2
2005-05-10 1 2
解答:
a,第一种方式
1.根据RQ进行group by 操作,即根据时间进行分组,
2.再求出同一时间胜和负的合计值
SELECT RQ,
SUM(CASE
WHEN SHENGFU = '胜' THEN
1
ELSE
0
END) 胜,
SUM(CASE
WHEN SHENGFU = '负' THEN
1
ELSE
0
END) 负
FROM RESULT
GROUP BY RQ;
SQL> SELECT RQ,
2 SUM(CASE
3 WHEN SHENGFU = '胜' THEN
4 1
5 ELSE
6 0
7 END) 胜,
8 SUM(CASE
9 WHEN SHENGFU = '负' THEN
10 1
11 ELSE
12 0
13 END) 负
14 FROM RESULT
15 GROUP BY RQ;
RQ 胜 负
---------- ---------- ----------
2005-05-10 1 2
2005-05-09 2 2
b.第二种方式
1.分别查询胜的次数及其时间,
2.再把两个结果集进行内连接
SELECT N.RQ, N.胜, M.负
FROM (SELECT RQ, COUNT(*) AS 胜
FROM RESULT
WHERE SHENGFU = '胜'
GROUP BY RQ) N
INNER JOIN (SELECT RQ, COUNT(*) AS 负
FROM RESULT
WHERE SHENGFU = '负'
GROUP BY RQ) M ON N.RQ = M.RQ;
SQL> SELECT N.RQ, N.胜, M.负
2 FROM (SELECT RQ, COUNT(*) AS 胜
3 FROM RESULT
4 WHERE SHENGFU = '胜'
5 GROUP BY RQ) N
6 INNER JOIN (SELECT RQ, COUNT(*) AS 负
7 FROM RESULT
8 WHERE SHENGFU = '负'
9 GROUP BY RQ) M ON N.RQ = M.RQ;
RQ 胜 负
---------- ---------- ----------
2005-05-10 1 2
2005-05-09 2 2
c.第三种方式
1.分别查询胜的次数及其时间
2、通过等值条件进行连接起来
SELECT N.RQ, N.胜, M.负
FROM (SELECT RQ, COUNT(*) AS 胜
FROM RESULT
WHERE SHENGFU = '胜'
GROUP BY RQ) N, (SELECT RQ, COUNT(*) AS 负
FROM RESULT
WHERE SHENGFU = '负'
GROUP BY RQ) M
WHERE N.RQ = M.RQ;
SQL> SELECT N.RQ, N.胜, M.负
2 FROM (SELECT RQ, COUNT(*) AS 胜
3 FROM RESULT
4 WHERE SHENGFU = '胜'
5 GROUP BY RQ) N, (SELECT RQ, COUNT(*) AS 负
6 FROM RESULT
7 WHERE SHENGFU = '负'
8 GROUP BY RQ) M
9 WHERE N.RQ = M.RQ;
RQ 胜 负
---------- ---------- ----------
2005-05-10 1 2
2005-05-09 2 2<pre class="sql" name="code">怎么把这样一个表儿
year month amount
1991 1 1.1
1991 2 1.2
1991 3 1.3
1991 4 1.4
1992 1 2.1
1992 2 2.2
1992 3 2.3
1992 4 2.4
查成这样一个结果
year m1 m2 m3 m4
1991 1.1 1.2 1.3 1.4
1992 2.1 2.2 2.3 2.4
create table AMOUNT
(
YEAR VARCHAR2(4),
MONTH VARCHAR2(2),
AMOUNT NUMBER(15,2)
);
insert into amount (YEAR, MONTH, AMOUNT)
values ('1991', '1', 1.10);
insert into amount (YEAR, MONTH, AMOUNT)
values ('1991', '2', 1.20);
insert into amount (YEAR, MONTH, AMOUNT)
values ('1991', '3', 1.30);
insert into amount (YEAR, MONTH, AMOUNT)
values ('1991', '4', 1.40);
insert into amount (YEAR, MONTH, AMOUNT)
values ('1992', '1', 2.10);
insert into amount (YEAR, MONTH, AMOUNT)
values ('1992', '2', 2.20);
insert into amount (YEAR, MONTH, AMOUNT)
values ('1992', '3', 2.30);
insert into amount (YEAR, MONTH, AMOUNT)
values ('1992', '4', 2.40);
思路:group by year统计年,再条件判断每个月,统计所在月,所在月的合计值显示出来select year,
(select sum(amount)
from amount m
where month = 1
and m.year = amount.year) as m1,
(select sum(amount)
from amount m
where month = 2
and m.year = amount.year) as m2,
(select sum(amount)
from amount m
where month = 3
and m.year = amount.year) as m3,
(select sum(amount)
from amount m
where month = 4
and m.year = amount.year) as m4
from amount
group by year;
SQL> select year,
2 (select sum(amount)
3 from amount m
4 where month = 1
5 and m.year = amount.year) as m1,
6 (select sum(amount)
7 from amount m
8 where month = 2
9 and m.year = amount.year) as m2,
10 (select sum(amount)
11 from amount m
12 where month = 3
13 and m.year = amount.year) as m3,
14 (select sum(amount)
15 from amount m
16 where month = 4
17 and m.year = amount.year) as m4
18 from amount
19 group by year;
YEAR M1 M2 M3 M4
---- ---------- ---------- ---------- ----------
1991 1.1 1.2 1.3 1.4
1992 2.1 2.2 2.3 2.4<pre class="sql" name="code">查询员工服务的年限
SELECT ENAME,
TRUNC(MONTHS_BETWEEN(SYSDATE, HIREDATE) / 12) YEAR,
TRUNC(MOD(MONTHS_BETWEEN(SYSDATE, HIREDATE), 12)) MONTH,
TRUNC(MOD(SYSDATE - HIREDATE, 30)) DAY
FROM EMP;
SQL> SELECT ENAME,
2 TRUNC(MONTHS_BETWEEN(SYSDATE, HIREDATE) / 12) YEAR,
3 TRUNC(MOD(MONTHS_BETWEEN(SYSDATE, HIREDATE), 12)) MONT
4 TRUNC(MOD(SYSDATE - HIREDATE, 30)) DAY
5 FROM EMP;
ENAME YEAR MONTH DAY
---------- ---------- ---------- ----------
SMITH 34 7 13
ALLEN 34 5 8
WARD 34 5 6
JONES 34 3 27
MARTIN 33 10 28
BLAKE 34 2 28
CLARK 34 1 19
SCOTT 28 3 9
KING 33 8 8
TURNER 33 10 18
ADAMS 28 2 5
ENAME YEAR MONTH DAY
---------- ---------- ---------- ----------
JAMES 33 7 22
FORD 33 7 22
MILLER 33 6 1
已选择14行。<pre class="sql" name="code">统计每年入职的员工个数,效果如下:
TOTAL 1980 1981 1982 1987 1990
-------- ---------- ---------- ---------- ---------- ----------
14 1 10 1 2 0
方式一:
思路:
通过group by 入职日期的年份来获取,适用统计所有年份的入职人数
select to_char(hiredate, 'yyyy') AS 年份, count(*)
from emp
group by to_char(hiredate, 'yyyy')
order by 1
SQL>
1 select to_char(hiredate, 'yyyy') AS 年份, count(*)
2 from emp
3 group by to_char(hiredate, 'yyyy')
4* order by 1
SQL> /
年份 COUNT(*)
---- ----------
1980 1
1981 10
1982 1
1987 2
方式二:
显示总数,并按条件求每年的入职人数(繁锁,但显示直观,适用统计特定年份的人数,查询次数多)
select (select count(*) from emp) total,
(select count(*) from emp where to_char(hiredate, 'yyyy') = '1980') "1980",
(select count(*) from emp where to_char(hiredate, 'yyyy') = '1981') "1981",
(select count(*) from emp where to_char(hiredate, 'yyyy') = '1982') "1982",
(select count(*) from emp where to_char(hiredate, 'yyyy') = '1987') "1987",
(select count(*) from emp where to_char(hiredate, 'yyyy') = '1990') "1990"
from emp
where rownum = 1
1 select
2 (select count(*) from emp) total,
3 (select count(*) from emp where to_char(hiredate, 'yyyy')='1980') "1980",
4 (select count(*) from emp where to_char(hiredate, 'yyyy')='1981') "1981",
5 (select count(*) from emp where to_char(hiredate, 'yyyy')='1982') "1982",
6 (select count(*) from emp where to_char(hiredate, 'yyyy')='1987') "1987",
7 (select count(*) from emp where to_char(hiredate, 'yyyy')='1990') "1990"
8 from
9 emp
10 where
11* rownum=1
SQL> /
TOTAL 1980 1981 1982 1987 1990
---------- ---------- ---------- ---------- ---------- ----------
14 1 10 1 2 0
方法三:
思路:
和方法二显示的效果相同 ,但是比第二种方法优,通过函数判断,减少查询次数
select count(*) total,
sum(Decode(to_char(hiredate, 'yyyy'), '1980', 1, 0)) "1980",
sum(Decode(to_char(hiredate, 'yyyy'), '1981', 1, 0)) "1981",
sum(Decode(to_char(hiredate, 'yyyy'), '1982', 1, 0)) "1982",
sum(Decode(to_char(hiredate, 'yyyy'), '1987', 1, 0)) "1987",
sum(Decode(to_char(hiredate, 'yyyy'), '1990', 1, 0)) "1990"
from emp
1 select
2 count(*) total,
3 sum(Decode(to_char(hiredate, 'yyyy'), '1980', 1, 0)) "1980",
4 sum(Decode(to_char(hiredate, 'yyyy'), '1981', 1, 0)) "1981",
5 sum(Decode(to_char(hiredate, 'yyyy'), '1982', 1, 0)) "1982",
6 sum(Decode(to_char(hiredate, 'yyyy'), '1987', 1, 0)) "1987",
7 sum(Decode(to_char(hiredate, 'yyyy'), '1990', 1, 0)) "1990"
8 from
9* emp
SQL> /
TOTAL 1980 1981 1982 1987 1990
---------- ---------- ---------- ---------- ---------- ----------
14 1 10 1 2 0
获取当前时间,显示为 xxxx年xx月xx日 xx时xx分xx秒 的格式
SQL(使用双引号向日期格式中添加字符):
select to_char(sysdate, 'yyyy"年"mm"月"dd"日" hh"时"mi"分"ss"秒"') from dual;
结果:
TO_CHAR(SYSDATE,'YYYY"年"MM
---------------------------
2012年03月08日 01时04分01秒
假如数据量很大约1000万条,写一个你认为最高效的SQL,用一个SQL计算以下四种人
sal>9999 and age>35
sal>9999 and age<35
sal<9999 and age>35
sal<9999 and age>35
case when方式
select sum(case
when sal > 9999 and
TRUNC(MONTHS_BETWEEN(SYSDATE, HIREDATE) / 12) > 35 then
1
else
0
end) A,
sum(case
when sal > 9999 and
TRUNC(MONTHS_BETWEEN(SYSDATE, HIREDATE) / 12) < 35 then
1
else
0
end) B,
sum(case
when sal < 9999 and
TRUNC(MONTHS_BETWEEN(SYSDATE, HIREDATE) / 12) > 35 then
1
else
0
end) C,
sum(case
when sal < 9999 and
TRUNC(MONTHS_BETWEEN(SYSDATE, HIREDATE) / 12) < 35 then
1
else
0
end) D
from emp;
SQL> select sum(case
2 when sal > 9999 and
3 TRUNC(MONTHS_BETWEEN(SYSDATE, HIREDATE) / 12) > 35 then
4 1
5 else
6 0
7 end) A,
8 sum(case
9 when sal > 9999 and
10 TRUNC(MONTHS_BETWEEN(SYSDATE, HIREDATE) / 12) < 35 then
11 1
12 else
13 0
14 end) B,
15 sum(case
16 when sal < 9999 and
17 TRUNC(MONTHS_BETWEEN(SYSDATE, HIREDATE) / 12) > 35 then
18 1
19 else
20 0
21 end) C,
22 sum(case
23 when sal < 9999 and
24 TRUNC(MONTHS_BETWEEN(SYSDATE, HIREDATE) / 12) < 35 then
25 1
26 else
27 0
28 end) D
29 from emp;
A B C D
---------- ---------- ---------- ----------
0 0 0 17
Oracle层级查询
--层次化查询,注意prior是Oracle内置的操作符,仅用来处理层次化查询
select level,
lpad(' ', 2 * (level - 1)) || last_name "EmpName",
employee_id,
manager_id,
first_name,
last_name,
hire_date
from employees
--表示根节点为manager_id
start with manager_id is null
--prior表示父行的employee_id,等于当前行的manager_id
connect by manager_id = prior employee_id
order by level;
</listener>
说明:本人于ITEYE创建于2013年,现转移到CSDN
</listener>
相关文章推荐
- Oracle分析函数
- SQL优化技巧(Oracle)
- Oracle查询重复数据与删除重复记录方法
- 使用命令解锁用户。命令为:alter user username account unlock;
- powerDesigner 连接Oracle 报Unable to connect SQLState=08004 解决方法
- oracle 汉字 order by方法
- Oracle日期范围查询交叉查询方法
- MyBatis批量操作_ORACLE
- Oracle异常处理
- oracle 11g 的安装
- Oracle Data Recovery Advisor(DRA)
- oracle 数据库查询排序小结
- Oracle数据库--实用操作(3) PL/SQL
- oracle生成行方法
- Oracle用户管理和角色管理
- oracle imp dmp
- Oracle用户权限分配
- Oracle数据库--实用操作(2) 数据库对象
- oracle11g导出DMP不能导空表解决方法
- Oracle数据库和实例的区别