您的位置:首页 > 其它

[每日一题] OCP1z0-047 :2013-07-22 group by 子句........................................................11

2013-07-22 00:02 615 查看
有疑问可以去itpub讨论:http://www.itpub.net/thread-1803877-1-1.html







这道题就是考where group by having的顺序。。。

答案A不正确:where应该放在group by前面

答案B不正确:having子句是用多行函数(sum,avg,max,min,count)等做为条件

答案C不正确:where应该放在group by前面





参考如下:(其实having 也可以放在group by前面)



SELECT column, group_function

FROM table

[WHERE condition]

[GROUP BY group_by_expression]

[H***ING group_condition]

[ORDER BY column];



答案:D

**********************************************************

一、group by分组注意:

drop table t;

drop table t1;

create table t(id number,dt date);

create table t1(id number,dt date);

insert into t values(1,sysdate);

insert into t1 values(1,sysdate+1);

insert into t1 values(1,sysdate+2);

commit;

--表中不正确

select t.id,max(t1.dt) mdt

from t,t1 where t.id=t1.id;

--dual结合select 常量,始终返回一行,不管dual有多少行,所以正确

--在一般表里会出错,这个世界的规则有普通规则和特殊规则,如果都去遵守普遍规则,那么将会世界太平,特殊规则不用刻意去追求和遵循

with t as

(select 1 id,sysdate dt from dual),

t1 as

(select 1 id,sysdate+1 dt from dual union all

select 1,sysdate+2 from dual)

select t.id,max(t1.dt) mdt

from t,t1 where t.id=t1.id;

--t1.id是多行,不行

with t as

(select 1 id,sysdate dt from dual),

t1 as

(select 1 id,sysdate+1 dt from dual

UNION ALL

select 1,sysdate+2 from dual)

select t1.id,max(t1.dt) mdt

from t,t1 where t.id=t1.id;

--让tm来源于表,照样出错,和dual构造都有关系

with tm as

(select 1 id,sysdate dt from t),

t1 as

(select 1 id,sysdate+1 dt from dual union all

select 1,sysdate+2 from dual)

select t1.id,max(t1.dt) mdt

from tm,t1 where tm.id=t1.id;

select dummy from dual;

--错误

select dummy from dual having count(*)=1;

--错误

with t as

(select dummy from dual)

select dummy from t having count(*)=1;

--用dummy就算取别名也出错,dummy列里不是常量??因为dummy允许多行

with t as

(select dummy x from dual)

select x from t having count(*)=1;

--正确,不用dummy,因为select 常量 from dual;不管dual有多少行,始终返回一行

with t as

(select 'X' x from dual)

select x from t having count(*)=1;

select * from dual;

--给dual插入一条数据

insert into sys.dual values('Y');

----------------------------------------------------神奇的dual------------------------------------------------------------------

SQL> select dummy from dual;



DUMMY

-----

X

Y



SQL> select 'X' x from dual;



X

-

X



SQL> drop table m;



Table dropped



SQL> create table m(d varchar2(10));



Table created



SQL> insert into m values('a');



1 row inserted



SQL> insert into m values('b');



1 row inserted



SQL> select 'X' x from m;



X

-

X

X

二、having写在group by前后都一样

drop table t;

create table t(id number,name varchar2(10),sal number);

insert into t values(1,'a',2000);

insert into t values(1,'b',3000);

insert into t values(2,'c',1000);

insert into t values(2,'x',2000);

insert into t values(3,'d',5000);

insert into t values(4,'e',4000);

commit;

delete from t where id=1;

--下面的结果是一样的,但是最好用第2种,可读性强

select id,max(sal),count(*) from t having count(*)>1 group by id;

select id,max(sal),count(*) from t group by id having count(*)>1;

俩个sql有 什么区别?

1. select job,sum(sal) from emp t group by job having sum(sal) > 4200

2. select job,sum(sal) from emp t having sum(sal) > 4200 group by job

查询结果是一样的,具体这俩句有区别吗??

没有区别,oracle having可以放在前后,常规写法第1种

三、理解分组
http://www.itpub.net/thread-1042899-1-1.html
如何实现比较复杂的分组、小计与合计

--测试代码

create table t_dist

(

TYPE_CD NUMBER,

BUYER_ID VARCHAR2(50),

ORDER_DT DATE,

SO_ID VARCHAR2(50) not null,

STOCK_ID VARCHAR2(50) not null,

UNIT_PRICE NUMBER,

DISCOUNT NUMBER,

QTY NUMBER

);

truncate table t_dist;

insert into t_dist values(1,'CN1001',to_date('2008-04-01','yyyy-mm-dd'),'S9001','29110311',50,10,8);

insert into t_dist values(1,'CN1001',to_date('2008-04-02','yyyy-mm-dd'),'S9002','29110312',60,20,2);

insert into t_dist values(1,'CN1001',to_date('2008-04-03','yyyy-mm-dd'),'S9003','29110313',70,15,3);

insert into t_dist values(2,'CN1001',to_date('2008-04-04','yyyy-mm-dd'),'S9004','29110312',60,15,5);

insert into t_dist values(2,'CN1001',to_date('2008-04-05','yyyy-mm-dd'),'S9005','29110311',70,10,6);

insert into t_dist values(3,'CN1001',to_date('2008-04-06','yyyy-mm-dd'),'S9006','29110313',55,20,4);

insert into t_dist values(3,'CN1001',to_date('2008-04-06','yyyy-mm-dd'),'S9007','29110311',40,10,3);

insert into t_dist values(3,'CN1001',to_date('2008-04-07','yyyy-mm-dd'),'S9008','29110312',50,50,5);

insert into t_dist values(3,'CN1001',to_date('2008-04-07','yyyy-mm-dd'),'S9009','29110313',80,10,2);

insert into t_dist values(1,'CN1001',to_date('2008-04-08','yyyy-mm-dd'),'S9010','29110311',65,10,1);

commit;

请问:如何实现如下结果,谢谢!

即计算按stock_id,type_cd,distount分组,计算每个产品的销售额(qty*unit_price)及销售百分比,并有小计

STOCK_ID TYPE_CD DISCOUNT ***G_PRICE SUM_TOT PCT

-------------------------------------------------------------------------------------------------

29110311 1 10 57.50 465 46.27%

29110311 2 10 70.00 420 41.79%

29110311 3 10 40.00 120 11.94%

小计 55.83 1005 100.00%

29110312 1 20 60.00 120 17.91%

29110312 2 15 60.00 300 44.78%

29110312 3 50 50.00 250 37.31%

小计 56.67 670 100.00%

29110313 1 15 70.00 210 35.59%

29110313 3 10 80.00 160 27.12%

29110313 3 20 55.00 220 37.29%

小计 68.33 590 100.00%

哦, 我明白了PCT的意思了, 以后要把问题描述的清楚点![有没有奖励啊? ]

具体如下:

SQL> select case when grouping_id(type_cd,discount) = 3 then '小计' else stock_id end stock_id,

2 type_cd,discount,avg(unit_price ) ***G_PRICE,

3 sum(qty*unit_price) SUM_TOT,

4 RATIO_TO_REPORT(sum(qty*unit_price )) over(partition by stock_id)*2 PCT

5 from t_dist

6 group by stock_id,rollup((type_cd,discount));

STOCK_ID TYPE_CD DISCOUNT ***G_PRICE SUM_TOT PCT

-------------------------------------------------- ---------- ---------- ---------- ---------- ----------

29110311 1 10 57.5 465 0.46268656

29110311 2 10 70 420 0.41791044

29110311 3 10 40 120 0.11940298

小计 56.25 1005 1

29110312 1 20 60 120 0.17910447

29110312 2 15 60 300 0.44776119

29110312 3 50 50 250 0.37313432

小计 56.6666666 670 1

29110313 1 15 70 210 0.35593220

29110313 3 10 80 160 0.27118644

29110313 3 20 55 220 0.37288135

小计 68.3333333 590 1

12 rows selected

QUOTE:

--------------------------------------------------------------------------------

原帖由 dingjun123 于 2011-2-23 10:13 发表

理解分组的概念

sum(sum(........之后相当于什么样的分组,后面又来个sum(.............

当然报错了

--------------------------------------------------------------------------------

还是不理解 ,

暂不看sum,这里的 分子。分母是一样的啊。只是sum了分母,还是sum了分子;

相当于 sum(sum(a))/sum(a) 与 sum(a)/sum(sum(a)) ,后面的行的通,前面的怎么可能行不通啊

理解这个

with t as

(select mod(level,2) id from dual connect by level<10 )

select id,sum(id) from t

group by id;

with t as

(select mod(level,2) id from dual connect by level<10 )

select-- id,

sum(sum(id)) from t

group by id;

第2句为什么不能有id,因为sum(sum,外面的sum相当于全量分组了,相当于

with t as

(select mod(level,2) id from dual connect by level<10 )

select sum(x) from (

select id,

sum(id) x from t

group by id

);

那么当然不能有非汇总列在select里显示啊

一针见血啊。高~,很耐心的指导啊

还有个疑问

select

sum(sum(QTY )) over (partition by stock_Id) PCT1 ,

sum(sum(QTY )) over (partition by stock_Id,grouping(type_cd)) PCT2

from t_dist

group by rollup(stock_id,(type_cd,DISCOUNT))

PCT1,PCT2有何区别?我实在是想不懂了。

等价于这个

select sum(x) over (partition by stock_Id) PCT1,

sum(x) over(partition by stock_Id,gp) PCT2

from (

select

sum(QTY ) x,stock_Id,grouping(type_cd) gp

from t_dist

group by rollup(stock_id,(type_cd,DISCOUNT))

);

看红色部分就知道第3个加了grouping的值,那么分区(分组)是不同的,所以两个结果不同

QQ:252803295

学习交流QQ群:

DSI&Core Search Ⅰ 群:127149411(技术:已满)

DSI&Core Search Ⅱ 群:177089463(技术:未满)

DSI&Core Search Ⅲ 群:284596437(技术:未满)

DSI&Core Search Ⅳ 群:192136702(技术:未满)

DSI&Core Search Ⅴ 群:285030382(闲聊:未满)



MAIL:oracledba_cn@hotmail.com

BLOG: http://blog.csdn.net/guoyjoe

WEIBO:http://weibo.com/guoyJoe0218

ITPUB: http://www.itpub.net/space-uid-28460966.html

OCM: http://education.oracle.com/education/otn/YGuo.HTM
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐