sql每日一题(20200423)

引自:https://mp.weixin.qq.com/s?__biz=MzA3MTg4NjY4Mw==&mid=2457305153&idx=4&sn=16f0a3aa3348146e3deaedd068a78d49&chksm=88a59275bfd21b631257bd78785a439334349805b4ccaba3aaafa02893a43905c9eaebfa0f7d&mpshare=1&scene=1&srcid=&sharer_sharetime=1588907149232&sharer_shareid=18c156b37f741bf9989098e28bf33e09&exportkey=AXRm7GRYX8OeOrMWH459APE%3D&pass_ticket=A1ttd35av4LYriQVQwl7gUMGSBTJ9Nm9iNWoea0RNlgp2DTQUPkM8WEmUoLMzscn#rd

感谢出题者,如有冒犯,请与我联系,希望和大家一起学习交流。(目前使用oracle数据库环境编写sql)

题目:
有如下两张表A和B
sql每日一题(20200423)

表A

sql每日一题(20200423)

表B

 

希望得到如下结果:
sql每日一题(20200423)

 

anum表示每个人参加的项目数,bnum表示每个人在各自项目中胜利的次数该如何写这个查询?

 

读者可以试着自己想写,再往下翻...

 

 

 

 

 

 

 

解答:

  • 两表关联count聚合统计(null值不参与计算)
sys@wil> WITH T AS
  2    (SELECT '跑步' AID, '张三' BID
  3      FROM DUAL
  4    UNION ALL
  5    SELECT '游泳' AID, '张三' BID
  6      FROM DUAL
  7    UNION ALL
  8    SELECT '跳远' AID, '李四' BID
  9      FROM DUAL
 10    UNION ALL
 11    SELECT '跳高' AID, '王五' BID
 12      FROM DUAL),
 13  TT AS
 14    (SELECT '跑步' AID, '张三' BID, '胜' CID
 15      FROM DUAL
 16    UNION ALL
 17    SELECT '游泳' AID, '张三' BID, '胜' CID
 18      FROM DUAL
 19    UNION ALL
 20    SELECT '跳高' AID, '王五' BID, '胜' CID
 21      FROM DUAL)
 22  SELECT T.BID, COUNT(T.BID) ANUM, COUNT(TT.CID) BNUM
 23    FROM T
 24    LEFT JOIN TT
 25      ON T.BID = TT.BID
 26      AND T.AID = TT.AID
 27    GROUP BY T.BID
 28    ORDER BY 2 DESC, 1;

BID        ANUM       BNUM
---- ---------- ----------
张三          2          2
李四          1          0
王五          1          1

 

  • 分别对表A和表B进行聚合后再关联
sys@wil> WITH T AS
  2    (SELECT '跑步' AID, '张三' BID
  3      FROM DUAL
  4    UNION ALL
  5    SELECT '游泳' AID, '张三' BID
  6      FROM DUAL
  7    UNION ALL
  8    SELECT '跳远' AID, '李四' BID
  9      FROM DUAL
 10    UNION ALL
 11    SELECT '跳高' AID, '王五' BID
 12      FROM DUAL),
 13  TT AS
 14    (SELECT '跑步' AID, '张三' BID, '胜' CID
 15      FROM DUAL
 16    UNION ALL
 17    SELECT '游泳' AID, '张三' BID, '胜' CID
 18      FROM DUAL
 19    UNION ALL
 20    SELECT '跳高' AID, '王五' BID, '胜' CID
 21      FROM DUAL)
 22  SELECT T3.BID, T3.CN ANUM, NVL(T4.CN, 0) BNUM
 23    FROM (SELECT BID, COUNT(*) CN FROM T GROUP BY BID) T3
 24    LEFT JOIN (SELECT BID, COUNT(*) CN FROM TT GROUP BY BID) T4
 25      ON T3.BID = T4.BID
 26    ORDER BY 2 DESC, 1;

BID        ANUM       BNUM
---- ---------- ----------
张三          2          2
李四          1          0
王五          1          1
  • oracle特有语法(数据量少时,可先对关联查询表进行谓词推进,12c可以用lateral实现):
sys@ESWIFT> WITH T AS
  2    (SELECT '跑步' AID, '张三' BID
  3       FROM DUAL
  4     UNION ALL
  5     SELECT '游泳' AID, '张三' BID
  6       FROM DUAL
  7     UNION ALL
  8     SELECT '跳远' AID, '李四' BID
  9       FROM DUAL
 10     UNION ALL
 11     SELECT '跳高' AID, '王五' BID
 12       FROM DUAL),
 13   TT AS
 14    (SELECT '跑步' AID, '张三' BID, '胜' CID
 15       FROM DUAL
 16     UNION ALL
 17     SELECT '游泳' AID, '张三' BID, '胜' CID
 18       FROM DUAL
 19     UNION ALL
 20     SELECT '跳高' AID, '王五' BID, '胜' CID
 21       FROM DUAL)
 22   SELECT T3.*,T4.COLUMN_VALUE BNUM FROM (SELECT BID, COUNT(*)ANUM FROM T GROUP BY BID) T3,
 23               TABLE(CAST(MULTISET
 24                          (SELECT COUNT(*) CN FROM TT WHERE BID = T3.BID) AS
 25                          SYS.ODCIVARCHAR2LIST)) T4
 26    ORDER BY 2 DESC, 1;

BID        ANUM BNUM
---- ---------- ------------------------------
张三          2 2
李四          1 0
王五          1 1

 

如有其它解题思路,欢迎一起交流学习。

 

上一篇:JS利用 Sea.js 实现模块化:拖拽、缩放及范围限制


下一篇:oracle自动生成表转大小写