V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
iugo
V2EX  ›  问与答

SQL 一对多关系表的统计 的更优解是什么?

  •  
  •   iugo · 2019-06-24 17:08:03 +08:00 · 1355 次点击
    这是一个创建于 1739 天前的主题,其中的信息可能已经有所发展或是发生改变。

    比如问题是: 成绩达到过 80 以上的同学有几位?

    示例表:

    table test_students
    name | studentID
    Jim  | 1001
    
    table test_scoresheet
    studentID | date       | score
    1001      | 2019-09-24 | 81
    1001      | 2019-10-24 | 85
    

    以 PostgreSQL 为例:

    创建测试表及数据:

    CREATE TABLE "public"."test_students" ("studentID" serial,"name" text, PRIMARY KEY ("studentID"));
    INSERT INTO "public"."test_students" ("studentID", "name") VALUES ('1001', 'Jim');
    
    CREATE TABLE "public"."test_scoresheet" ("id" serial,"studentID" int4, "date" text, "score" int4, PRIMARY KEY ("id"));
    INSERT INTO "public"."test_scoresheet" ("id", "studentID", "date", "score") VALUES ('1', '1001', '2019-09-24', '81');
    INSERT INTO "public"."test_scoresheet" ("id", "studentID", "date", "score") VALUES ('2', '1001', '2019-10-24', '85');
    

    已知但预计不够良好的解法:

    SELECT COUNT(id) FROM (
    	SELECT
    		DISTINCT ON(test_students."studentID")
    		test_students."studentID" AS id
    	FROM test_students
    		INNER JOIN test_scoresheet ON test_students."studentID" = test_scoresheet."studentID"
    ) AS some_students;
    
    5 条回复    2019-06-25 18:49:21 +08:00
    dingz
        1
    dingz  
       2019-06-24 18:27:11 +08:00 via Android   ❤️ 1
    select count(*) from test_student WHERE studentID IN (select studentID FROM test_scoresheet where score>80)
    akira
        2
    akira  
       2019-06-24 18:34:25 +08:00
    对 studentID 做去重 汇总就好了啊 , test_students 表都不需要
    iugo
        3
    iugo  
    OP
       2019-06-25 17:10:16 +08:00
    @dingz 如果 test_scoresheet 量级是百万, 不知道哪种做法效率更高.
    iugo
        4
    iugo  
    OP
       2019-06-25 17:11:10 +08:00
    @akira 是我的例子不够好, 实际上是需要统计 test_students 中的一些数据的, 不是简单地记数.
    akira
        5
    akira  
       2019-06-25 18:49:21 +08:00
    @iugo 那就是 1l 的写法,加个 distinct,或者考虑在内嵌个 max 子查询.

    如果你的写法 没有出现性能问题,其实也不需要去管太多的,
    能出正确结果的 sql 就是好 sql
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2691 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 15:45 · PVG 23:45 · LAX 08:45 · JFK 11:45
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.