主表:
從表:
結果集: 查詢從表中年齡最大的一行數據,如果存在年齡相等的則為了保證唯一取id(主鍵)最大的一行。
一、利用sql子查詢嵌套
-- -------------------------------- -- 利用sql子查詢嵌套 -- -------------------------------- -- step 1. 子查詢:找到每組最大的子類年齡 select parent_id,max(child_age) from child group by parent_id; -- step 2. 找到符合的行 (很可能出現重復) select cc.* from child cc INNER JOIN (select parent_id,max(child_age) child_age from child group by parent_id) tmp on tmp.parent_id = cc.parent_id and tmp.child_age = cc.child_age order by cc.parent_id,cc.child_id; -- step 3. 為了解決重復需要再加一層,取唯一標識id最大/最小的一行 select max(cc.child_id) from child cc INNER JOIN (select parent_id,max(child_age) child_age from child group by parent_id) tmp on tmp.parent_id = cc.parent_id and tmp.child_age = cc.child_age group by cc.parent_id,cc.child_age -- step 4. 在3中就找到了符合條件行的id select * from parent pa LEFT JOIN (SELECT cc.* from child cc INNER JOIN (select max(cc.child_id) child_id from child cc INNER JOIN (select parent_id,max(child_age) child_age from child group by parent_id) tmp
on tmp.parent_id = cc.parent_id and tmp.child_age = cc.child_age group by cc.parent_id,cc.child_age) tmp on TMP.child_id = cc.child_id ) tmp on tmp.parent_id = pa.parent_id where 1=1 ORDER BY pa.parent_id;
二、利用oracle自帶的分析函數
-- -------------------------------- -- 利用oracle分析函數 -- -------------------------------- -- step-1:找到子類符合的id, DISTINCT去重 select DISTINCT first_value(cc.child_id) over(partition by cc.parent_id order by cc.parent_id,cc.child_age desc,cc.child_id desc) child_id from child cc; -- step-2: 符合的子類結果集 SELECT * from child cc where cc.child_id in( select DISTINCT first_value(cc.child_id) over(partition by cc.parent_id order by cc.parent_id,cc.child_age desc,cc.child_id desc) child_id from child cc ); SELECT * from child cc where EXISTS ( select 1 from ( select DISTINCT first_value(cc.child_id) over(partition by cc.parent_id order by cc.parent_id,cc.child_age desc,cc.child_id desc) child_id from child cc) tmp where tmp.child_id = cc.child_id ); -- step-3: 最終結果集 select * from parent pa LEFT JOIN child cc on cc.parent_id = pa.parent_id and cc.child_id in( select DISTINCT first_value(cc.child_id)over(partition by cc.parent_id order by cc.parent_id,cc.child_age desc,cc.child_id desc) from child cc) where 1=1 ORDER BY pa.parent_id
三、分析區別
sql嵌套當然要更通用點,而且看執行計划,它的效率、消耗都要比oracle少很多;
oracle分析函數感覺還是子查詢嵌套了一層,而且效率、消耗都比較高。
(才知道oracle的執行計划,完全不懂。只是看着sql嵌套查詢的執行計划高效很多)![C)6_@)R@9B)`EM9J]}87GY3 C)6_@)R@9B)`EM9J]}87GY3](/image/aHR0cHM6Ly9pbWFnZXMyMDE1LmNuYmxvZ3MuY29tL2Jsb2cvMTAyNTI3My8yMDE2MTEvMTAyNTI3My0yMDE2MTEyNTE3NDExNjk3MS05OTUxNDUyNi5wbmc=.png)
四、測試數據
-- ----------------------------- -- PARENT 父表 -- ----------------------------- CREATE TABLE "PARENT" ( "PARENT_ID" NUMBER NOT NULL , "PARENT_NAME" VARCHAR2(255 BYTE) NOT NULL ) LOGGING NOCOMPRESS NOCACHE; -- Records of PARENT INSERT INTO "PARENT" VALUES ('1', '周父'); INSERT INTO "PARENT" VALUES ('2', '吳父'); INSERT INTO "PARENT" VALUES ('3', '鄭父'); INSERT INTO "PARENT" VALUES ('4', '王父'); INSERT INTO "PARENT" VALUES ('5', '趙父'); -- Checks structure for table PARENT ALTER TABLE "PARENT" ADD CHECK ("PARENT_ID" IS NOT NULL); ALTER TABLE "PARENT" ADD CHECK ("PARENT_NAME" IS NOT NULL); -- ----------------------------- -- PARENT 子表 -- ----------------------------- CREATE TABLE "CHILD" ( "CHILD_ID" NUMBER NOT NULL , "CHILD_NAME" VARCHAR2(255 BYTE) NOT NULL , "CHILD_AGE" NUMBER NOT NULL , "PARENT_ID" VARCHAR2(255 BYTE) NOT NULL ) LOGGING NOCOMPRESS NOCACHE; -- ---------------------------- -- Records of CHILD -- ---------------------------- INSERT INTO "CHILD" VALUES ('1', '周一', '6', '1'); INSERT INTO "CHILD" VALUES ('2', '周二', '8', '1'); INSERT INTO "CHILD" VALUES ('3', '周三', '7', '1'); INSERT INTO "CHILD" VALUES ('4', '吳一', '5', '2'); INSERT INTO "CHILD" VALUES ('5', '吳二', '3', '2'); INSERT INTO "CHILD" VALUES ('6', '吳三', '5', '2'); INSERT INTO "CHILD" VALUES ('7', '吳四', '2', '2'); INSERT INTO "CHILD" VALUES ('8', '鄭一', '8', '3'); INSERT INTO "CHILD" VALUES ('9', '鄭二', '4', '3'); INSERT INTO "CHILD" VALUES ('10', '王一', '18', '4'); -- Checks structure for table CHILD ALTER TABLE "CHILD" ADD CHECK ("CHILD_ID" IS NOT NULL); ALTER TABLE "CHILD" ADD CHECK ("CHILD_NAME" IS NOT NULL); ALTER TABLE "CHILD" ADD CHECK ("CHILD_AGE" IS NOT NULL); ALTER TABLE "CHILD" ADD CHECK ("PARENT_ID" IS NOT NULL);



