V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
chaleaoch
V2EX  ›  数据库

不知道大家有没有遇到过一个 sql 连了 7,8 张表

  •  
  •   chaleaoch · 2017-03-04 13:32:59 +08:00 · 4265 次点击
    这是一个创建于 2828 天前的主题,其中的信息可能已经有所发展或是发生改变。
    在实际的生产环境中,这样会带来很大的效率问题吗?
    昨天面试一个大兄弟,单张表只有 7--8 万的记录.连 7,8 张表查询,需要 7--8 秒.我表示很差异.

    当然了目前我所遇到过的最大连表只连三张,单表数据也不是很大.大概是一张几千,另一张几百万的样子.

    不过很快就查出来了.
    86 条回复    2017-03-06 18:36:12 +08:00
    zhy0216
        1
    zhy0216  
       2017-03-04 13:47:17 +08:00
    也是最近刚看过...
    huiyue
        2
    huiyue  
       2017-03-04 14:26:09 +08:00
    连几张表不是问题。但这个速度太慢的,是可以优化。这点数据量应该都是在秒内出来的。
    flyingfz
        3
    flyingfz  
       2017-03-04 14:29:12 +08:00
    看项目的类型。 一般互联网类型项目,这种情况应该比较少。

    但在一些 管理系统 类型项目里,一个 sql 涉及 7 , 8 张表甚至更多,还是偶尔能见到。
    一般来说,不用连那么多表,可以改成子查询之类的。

    曾经有段时间,经常手写 Sql 做一些统计数据, Sql 语句在编辑器里要翻好几页(当然是格式化之后的 sql )。
    loading
        4
    loading  
       2017-03-04 14:29:22 +08:00 via Android
    看看有没有用 like 这些语句。
    KeepPro
        5
    KeepPro  
       2017-03-04 14:30:47 +08:00 via Android
    试试 nosql 这类的
    Infernalzero
        6
    Infernalzero  
       2017-03-04 14:53:50 +08:00   ❤️ 3
    连表一时爽,全服火葬场
    whiler
        7
    whiler  
       2017-03-04 15:00:58 +08:00   ❤️ 1
    连表一时爽,全服火葬场
    jjx
        8
    jjx  
       2017-03-04 15:06:28 +08:00   ❤️ 1
    给 lz 举个进销存的例子

    一个销售报表, 包括以下细分单据销售单 /销售退货单 /零售单 /零售退货单, 关联数据包括核算员工, 核算部门, 货品,货品类型, 品牌, 商业伙伴, 商业伙伴隶属区域

    报表需要实时统计需要 首先按用户权限 过滤允许的区域 /部门 /商品类型, 查询条件包括 品牌, 货品,货品类型, 货品标签, 合作伙伴标签, 员工, 部门等

    算算看, 需要多少表
    hector
        9
    hector  
       2017-03-04 15:07:39 +08:00   ❤️ 1
    我以前写的存储过程,大部分要连十几张表,还有各种自连接,临时表,加上各种 rollback ,存储过程递归你怕不怕,一个查询几个几百行,一个操作上万行
    jjx
        10
    jjx  
       2017-03-04 15:08:47 +08:00
    上面还漏了, 实际上我们的销售类单据还有 现款销售单
    liprais
        11
    liprais  
       2017-03-04 15:12:41 +08:00 via iPhone
    做分析很常见的,另外子查询也是关联
    7654
        12
    7654  
       2017-03-04 15:23:14 +08:00
    很常见的啊
    我们的报表最终所使用的 SQL 有几百行呢,连 7,8 张表算什么
    还跨数据库呢
    jarlyyn
        13
    jarlyyn  
       2017-03-04 15:26:21 +08:00
    看做什么业务了。

    电商的做过。

    订单,相关商品,支付信息,退款记录,配送记录,用户等等。

    不过都是通过主键链接的,只通过主键搜索索引。
    chaleaoch
        14
    chaleaoch  
    OP
       2017-03-04 15:33:59 +08:00
    @7654
    @jjx
    @hector
    我没说连多张表有问题或者不常见.
    我是很差异为什么单表几万的数据量查询出来的东西要好几秒钟.

    例如,只查询出三条数据,这个查询时间要几秒钟...
    有那么夸张吗?
    如果有,应该如何处理?
    dallaslu
        15
    dallaslu  
       2017-03-04 15:49:11 +08:00
    不如把表结构和查询语句都贴出来,让大家也诧异一下。
    wdlth
        16
    wdlth  
       2017-03-04 16:01:31 +08:00
    见过某 MIS 连接至少 20 个表,还加了 DISTINCT ,搞得他们请的 DB 顾问一脸懵逼。
    7654
        17
    7654  
       2017-03-04 16:11:52 +08:00
    r#14 @chaleaoch 这应该是 DBA 的事,优化索引,建 partition 等等
    当然硬件也要跟的上
    flniu
        18
    flniu  
       2017-03-04 16:46:53 +08:00
    "例如,只查询出三条数据,这个查询时间要几秒钟... "
    通常是缺少索引或查询写法导致不使用索引。少数情况是服务器性能、网络、乃至查询客户端的问题。
    flniu
        19
    flniu  
       2017-03-04 16:50:15 +08:00
    互联网项目、采用 ORM 的系统一般不会 join 这么多表;
    传统的管理信息系统里多表 join 较多;
    ETL 、报表类的系统里几十张表 join 都不少见。
    xeneizes
        20
    xeneizes  
       2017-03-04 17:02:03 +08:00
    join 不怕,我同事用 in ,直接卡死,真是大 2B 啊
    shijingshijing
        21
    shijingshijing  
       2017-03-04 17:28:26 +08:00   ❤️ 1
    join 太多自己都觉得麻烦,不过对于这种一个 associate 表,专门负责各个 index 关联的,除了 join ,再就是分解成子查询了,还有其他方法么?我也很想知道。

    #r13 @jarlyyn 你们是一条记录主键,关联这么多表的各条记录的 id ,这样实现的吧。
    我有一个问题是,如果要对这一条记录进行操作,是不是要分解为多个子查询?

    举个例子,我有一个功能是显示用户的累计消费金额。如果用户对一个订单的某个商品进行了退款操作,我要更新用户的累计消费金额,就得在退款的同时,更新这个关联表,然后通过关联表,查询对应的用户 id ,更新用户的累计消费金额。很麻烦,但是感觉也没有其他很好的办法。你们是怎么做的?

    还有就是这个累计金额,你们是在用户表里面单独定义了一个字段,还是每次都重新查表计算生成?我们是单独定义了一个字段,因为这个累计金额会很频繁的用到,比如用户登录之后提示,用户每次打开用户信息页面等等,每次都通过查询计算生成的话,感觉会占很大的开销。但是这样做的话,可能会有字段存储的值与实际值不一致的潜在风险,比如用户退货的时候需要更新这个字段,用户在降价之后申请价格保护也会更新这个字段,用户下新的订单会增加这个字段,我们现在是封装了一个函数,业务完成后自动 update ,目前业务逻辑梳理的还算是比较清晰,没有出过问题。但是如果以后有新手接手,忘记添加这一个操作,就有可能造成不匹配,所以一直想问问同行这种情况到底怎么处理算是 best practice 。
    chaleaoch
        22
    chaleaoch  
    OP
       2017-03-04 17:41:37 +08:00
    @dallaslu
    因为是面试别人的时候聊到这里了.所以我也不知道具体的 sql 是什么.
    crist
        23
    crist  
       2017-03-04 17:50:57 +08:00
    连表一时爽,全服火葬场
    Infernalzero
        24
    Infernalzero  
       2017-03-04 18:19:36 +08:00
    大致就是两种方法,拆分查询或者宽表冗余字段,拿空间换时间,后者只适用于一致性要求不是很高的场景
    系统做大了以后 join 和 count 是两种最大最常见的隐患,所以看阿里的规范里是限制了最多 3 表 join
    tumbzzc
        25
    tumbzzc  
       2017-03-04 18:25:53 +08:00 via Android
    在 hive 跑数据才爽。。。
    jarlyyn
        26
    jarlyyn  
       2017-03-04 18:44:11 +08:00
    @shijingshijing

    我们的业务压根就不是电商,不算什么 best practice

    计算金额 /库存的都记录所有 balance 信息。

    就是每一天变动的初始金额,变动值,结束金额,操作相关记录,时间。

    然后做一个缓存表,也就是是实际使用的库存 /积分 /现金值。

    按你的问题来说,信息错就错,无所谓。由于每一条记录都是有独立记录初始值的。

    一旦有问题是可以事后找出来的。有需要的话可以另外跑个进程定时去核查。

    有问题不可怕,谁的代码还没点问题,出了问题查不出才可怕。
    sobigfish
        27
    sobigfish  
       2017-03-04 18:59:32 +08:00
    chaleaoch
        28
    chaleaoch  
    OP
       2017-03-04 19:06:18 +08:00
    @sobigfish
    我不是 dba 也不是自身的后端开发.
    不过之前曾经看过一本书上说,视图更多的是一种权限控制和简化 sql 的作用.这是视图存在的意义.并不是说,因为视图可以提升 sql 的查询效率.
    chaleaoch
        29
    chaleaoch  
    OP
       2017-03-04 19:10:01 +08:00
    @Infernalzero
    大侠,请教下.
    拆分查询 是指讲一次查询分成多次(例如两次),然后在程序里面将这两次查询出来的结果在合并到一起.
    宽表冗余 就是没有关联关系,反范式设计.

    是这个意思不?

    另,join 和 count 是两种最大最常见的隐患.
    join 的隐患应该就是本楼出现的情况.没明白 count 是啥意思?

    所以看阿里的规范里是限制了最多 3 表 join
    这个是怎么做到的?
    eyp82
        30
    eyp82  
       2017-03-04 19:23:58 +08:00
    MySQL 之类的数据库这么搞有很大问题, 互联网业务几乎没这么玩的.
    不过传统的企业软件 ERP 什么的, 用 Oracle 数据库, 确实有类似的情况, 不过那也是开发人员懒, 把数据库当万能来用了.
    Oracle 多表 join 虽然表现比 MySQL 强太多, 但也最好别这么玩, 很容易成为 top sql.
    Infernalzero
        31
    Infernalzero  
       2017-03-04 19:49:34 +08:00
    @chaleaoch
    是这样没错
    怎么做到的?靠规范啊
    chaleaoch
        32
    chaleaoch  
    OP
       2017-03-04 19:52:19 +08:00
    @eyp82 是的,我面试那哥们做的就是 erp.
    大侠,估计解决方案也就两个了(#24)了吧?
    还有其他方案吗?

    (因为我下分工作也是做 erp...所以比较关心.)
    Infernalzero
        33
    Infernalzero  
       2017-03-04 19:53:53 +08:00
    另外除了人为规范以外,这个也可以做到系统里的,比如发布系统或者 review 系统中对提交的代码做这类检查,如果违反了规范就不允许 push 。这个其实也可以在运行时进行检查,不过不推荐,影响了执行效率,还是编译前检查比较合理,而且至少 TDDL 里默认没有限制
    ivvei
        34
    ivvei  
       2017-03-04 19:54:07 +08:00 via Android
    Databases are born to join.
    chaleaoch
        35
    chaleaoch  
    OP
       2017-03-04 20:01:24 +08:00
    @ivvei
    啥意思?
    dexterzzz
        36
    dexterzzz  
       2017-03-04 20:06:01 +08:00
    搞 BI 用列存储数据库,不用在乎多少 join
    bonfy
        37
    bonfy  
       2017-03-04 21:04:31 +08:00
    连几十个 表的都见过...各种 join...
    LEFT
        38
    LEFT  
       2017-03-04 21:23:38 +08:00 via iPhone
    我们厂光商品就涉及 6 张表了
    killerv
        39
    killerv  
       2017-03-04 21:32:34 +08:00
    遇到过, 8 个 join ,一个子查询,最大的一个是十几万的表,其他表都是几十条,耗时 30s ,能写出这样的 sql 我也是服
    fxxkgw
        40
    fxxkgw  
       2017-03-04 21:40:14 +08:00
    表示上周一直在做各种 join on as 操作。。。头都大了
    ebony0319
        41
    ebony0319  
       2017-03-04 21:44:56 +08:00
    cchilar
        42
    cchilar  
       2017-03-04 22:03:28 +08:00 via Android
    BI 里经常会遇到。如果没走索引,有时候说不定能跑半小时。
    shijingshijing
        43
    shijingshijing  
       2017-03-04 22:15:21 +08:00
    @chaleaoch 其实我比较关心的是,来一个真正的案例,然后用纯 join 实现,纯子查询实现,部分 join+部分子查询实现,各个方案都在尽量优化的情况下来 PK 一把。以前在做的时候,也是事先在网上做了调研的,貌似 Stackoverflow 上面有比较。不过我最终还是放弃了 join 而选择了子查询,这不是经过仔细的考量得出结论后选择的,我当时的直觉是如果是三四个表 join ,在 key 和索引的帮助下,效率应该也还可以,但是一旦表多了之后,我个人感觉数据库性能会有急剧的下降。当然这都是我自己的感觉。当时时间紧迫,业务急着上线,凭直觉做出了选择,后来业务也能扛得住就没有再去关心过这个问题。

    现在我确实也非常想听听碰到过这个问题的其他同行的经历以及对应的处理方法。
    CRVV
        44
    CRVV  
       2017-03-04 22:15:55 +08:00
    这事丝毫不奇怪

    而且,查询要花多少时间和 JOIN 了几张表,每张表里有几行,关系并不大。主要看 SQL 是怎么写的,有没有加正确的索引

    SELECT * FROM t1 CROSS JOIN t2 CROSS JOIN t3 WHERE t1.a || t2.b || t3.c LIKE '%abcd%' 当然很慢

    SELECT * FROM t1 INNER JOIN t2 ON t1.id = t2.id1 ... INNER JOIN t100 ON t1.id = t100.id1 WHERE t1.id < 10 AND t1.id > 0
    如果 t1 的 id 和其它表的 id1 都有 UNIQUE INDEX ,这个一定很快
    hj2002007
        45
    hj2002007  
       2017-03-04 22:21:07 +08:00
    现在 mysql5.7 优化了大量查询 其实 join 不是很耗时 关键还是 索引+合理利用 rendis 等缓存 mysql 的子查询效率不好 还是慎用
    阿里自己的 mysql 已经改成 不是 mysql 了吧
    join 尽量不要超十张表,太多的话 就做汇总表吧
    一般 一些不需要进行排序的字段 就不要 select 了 只 select 必要的字段 用于缓存的查询 这样在 一定数据量下 响应的速度也是很快的
    我还是喜欢 先用数据库解决问题 毕竟很多问题 都是关系问题。 确实解决不了 再用程序解决。
    mingyun
        46
    mingyun  
       2017-03-04 22:43:15 +08:00
    恐怖,工作几年没用过
    ikaros
        47
    ikaros  
       2017-03-04 22:56:48 +08:00
    连表多肯定不是问题,问题应该是连的字段没索引
    wuhanchu
        48
    wuhanchu  
       2017-03-04 23:50:32 +08:00
    还真的是见过。。
    renyiqiu
        49
    renyiqiu  
       2017-03-04 23:55:18 +08:00
    @hector 这不得累死那些后面接手的人,因为不是每个人的数据库基础都那么好,我其实比较讨厌偏向数据库来处理负责业务的公司
    dong3580
        50
    dong3580  
       2017-03-04 23:59:40 +08:00
    连了几个表是小事,我以前维护过的项目,甚至 MSSQL 和 MYSQL 连起来了,维护的头大,
    hj2002007
        51
    hj2002007  
       2017-03-05 00:00:05 +08:00
    @renyiqiu 如果对方写的好 还是可以学习的 多学点总是好的
    hj2002007
        52
    hj2002007  
       2017-03-05 00:00:44 +08:00
    @dong3580 怎么连的 很好奇啊
    dong3580
        53
    dong3580  
       2017-03-05 00:06:17 +08:00
    @hj2002007
    .NET 里面的 ado.net ,后来我给他改成了映射实体,然而效果不理想,我接手的时候打开一个关联列表页面,大约 50 条数据的联动信息(这个信息非常的多)大约 20s 。后来又回归到.NET 自带的连接查询封装起来,加了大量的缓存优化和任务,大约降到了 5S ,然后效果还是不好。

    总结下来,如果要是大量做到快,需要自己用基础的类来封装优化,用现成的 在量大且并发多的情况下完全不行。

    当然,这里已经不涉及到表优化之类的,加主键和视图已经不能满足了。
    wind3110991
        54
    wind3110991  
       2017-03-05 00:15:52 +08:00
    join 多少张表,其实并没有太大关系的,
    主要开发人员是别 XJB 乱用外键,最好别用,不然分分钟炸给你看
    hj2002007
        55
    hj2002007  
       2017-03-05 00:20:10 +08:00
    @dong3580 嗯嗯 受教受教 我都是用 php 都是自己写 sql 语句 没有 orm 之类 都是先把需求写成 sql 然后优化到可以接受的范围 再开始写程序。
    hj2002007
        56
    hj2002007  
       2017-03-05 00:24:49 +08:00
    @wind3110991 用程序来维护外键 不是挺好的嘛 不过 Hibernate 之类的 外键判断真是分分秒秒崩 啊
    wind3110991
        57
    wind3110991  
       2017-03-05 00:52:27 +08:00
    @hj2002007 带外键的关系数据库做集群或者容灾时,双主、主从同步都有无法预料的问题,坑太多,
    有时同步失败,只能重新做表
    konakona
        58
    konakona  
       2017-03-05 00:59:00 +08:00   ❤️ 1
    不是不行,只是效率奇低。
    1. 优化每张表的索引和碎片
    2. 尽量使用子查询,或先取出表 1 里相关的数据(通过 selec * from where ,或者使用 1 个子查询,比 LEFTJOIN 效率高一丢丢。数据量越多, LEFTJOIN 效率越低。)

    这么说:

    哪怕你将这 7-8 个表的数据,不写 where 。全部拿出来放到对应的 7-8 个变量里。通过程序语言(如 python 、 PHP )用逻辑语句( IF 和 foreach )去遍历,找到数据。效率都高出题主里的那种不知道多少倍。
    wind3110991
        59
    wind3110991  
       2017-03-05 01:01:58 +08:00
    @konakona 工程中最好不要使用 select *
    https://www.zhihu.com/question/37777220
    eyp82
        60
    eyp82  
       2017-03-05 02:57:37 +08:00
    @chaleaoch 要么看看能不能一条 SQL 拆开成多条执行(这个好像有些 MySQL DBA 推荐), 要么重新设计一下 schema, 适当增加冗余减少 join (看你的 DML 和查询的比例), 需要权衡.

    ERP 说实话也没太好的方案, 即使是 SAP 的 ERP, 那 SQL 抓出来也是让人头疼, 动不动几百行的 SQL 语句, 跑起来蜗牛一样, 先天不足再优化也不没大用. 估计大家都习惯了,反正并发也不会太高, 主要复杂在业务逻辑.
    inrenping
        61
    inrenping  
       2017-03-05 10:03:44 +08:00
    不是一般都写成视图和表值函数么
    chaleaoch
        62
    chaleaoch  
    OP
       2017-03-05 12:00:49 +08:00
    @eyp82
    您说的先天不足应该就是只 erp 的业务坑爹吧?
    chaleaoch
        63
    chaleaoch  
    OP
       2017-03-05 12:01:31 +08:00
    @eyp82
    难道互联网 /电商项目就没有这么复杂的业务吗?
    erp 也可以做成电商啊~!
    (个人浅显理解.)
    phx13ye
        64
    phx13ye  
       2017-03-05 14:56:39 +08:00
    join 还好,笛卡尔积直接血崩
    chaleaoch
        65
    chaleaoch  
    OP
       2017-03-05 15:00:39 +08:00
    @phx13ye
    请问,那种情况下是笛卡尔积那种情况下不会?
    phx13ye
        66
    phx13ye  
       2017-03-05 15:22:50 +08:00
    @chaleaoch mysql 下,用`,` `[cross|inner] join` 指定两个表但是没有`on`,`using`等条件限制的话就会由内联接变成笛卡尔积啊

    具体你自己看一下查询的行数是不是两表数据量 M*N 也可以判断
    findex
        67
    findex  
       2017-03-05 16:38:40 +08:00 via iPhone
    @konakona 一开始用的 sql 链表结构,后来用的是同 id 结构,再后来用的是 nosql 结构。统一整体的就是每条记录都带一个 ID 。 现在在项目中用 sql 结构带 jsonp 数据类型。
    我觉得吧,针对不同的需求用什么样的数据解决方案。如果是网游的话,肯定不能用这样的多表结构。设计的时候多留点数据也比重复查表效率高。
    ivvei
        68
    ivvei  
       2017-03-06 00:17:30 +08:00 via Android
    @shijingshijing 你需要了解一下数据库的优化器。
    ivvei
        69
    ivvei  
       2017-03-06 00:18:45 +08:00 via Android
    @konakona 子查询和 left join 又不等价,你是怎么拿到一块去比的?
    torbrowserbridge
        70
    torbrowserbridge  
       2017-03-06 08:32:40 +08:00 via iPhone   ❤️ 1
    前几天刚遇到,同为 ERP 系统, 5 表 join ,之前查询 55 秒,加了一个索引只需要 0.025 秒
    chaleaoch
        71
    chaleaoch  
    OP
       2017-03-06 09:19:26 +08:00
    @torbrowserbridge 感谢分享心得.
    superkey
        72
    superkey  
       2017-03-06 09:39:03 +08:00
    遇到最多的就是 6 张表,说到底都是数据库设计的时候留下的锅.
    solaya
        73
    solaya  
       2017-03-06 09:43:47 +08:00
    做 erp 遇到连很多张表
    xvx
        74
    xvx  
       2017-03-06 09:58:17 +08:00 via iPhone
    我这里 join 十几个的都很常见……
    konakona
        75
    konakona  
       2017-03-06 11:20:05 +08:00
    @ivvei 没毛病啊,他们做的事情是一样的,只是查询语句和查询方式(提供结果的过程)不同,还有他们的过表方式也不同。性价比就在这个地方。他们没有一定限定哪些情况必须用 LEFT JOIN 也没有限定哪些情况必须用子查询。大部分情况下,我都建议子查询,或者说,大部分被坑过的都用子查询了。 哎, talk is cheep ,不如 show 你的 code 。大家来看下可以优化的地方具体是怎么样的吧。
    konakona
        76
    konakona  
       2017-03-06 11:22:54 +08:00
    并非我不用 LEFT JOIN ,RIGHT JOIN ,UNION JOIN. 有以下几种情况我会用:
    1. 框架支持 VIEWMODEL (其实就是帮我串接语句)
    2. 表优化做的好
    3. 每个表的数据量不超过 50w ,或者不太可能在 3 年内增长迅速(一些业务量低,偏向于静态数据,不怎么变化的);表数量大约在 5-8 个以为。


    -。- 这样查询的效率仍然很高,而且开发快捷,易于维护。

    经验告诉我们啥时候用啥……
    konakona
        77
    konakona  
       2017-03-06 11:23:38 +08:00
    我做的是教务系统,涉及到 9 个角色所操作的 4 个平台;以及 2 个 App 终端。业务量很大。
    labasq
        78
    labasq  
       2017-03-06 14:04:49 +08:00
    我 join 了十几个表啊?
    labasq
        79
    labasq  
       2017-03-06 14:05:25 +08:00
    我 join 了十几个表啊?
    难道要用嵌套子查询,或者主表出来循环查附表、?
    cncqw
        80
    cncqw  
       2017-03-06 14:37:43 +08:00
    为什么不先把单表数据查出来再用程序处理?
    nilai
        81
    nilai  
       2017-03-06 17:07:43 +08:00
    都让开都让开, 这是正文教务系统中的一句 SQL 如下:
    select * from (select case when a.kcxzdm is null then '98' else a.kcxzdm end kcxzdm,a.kcxzmc,case when a.xfyq is null then 0 else to_number(a.xfyq) end xfyq ,b.xfh1,b.xfh2,to_number(to_number((case when a.xfyq is null then 0 else to_number(a.xfyq) end))-to_number(b.xfh1)) xfc from (select * from jxjhxfyqview where jxjhh=(select dqszj||zydm from xsjbxxb where xh='0407100522')) a left join (select kcxz,case when sum(xf1) is null then 0 else sum(xf1) end xfh1,case when sum(xf2) is null then 0 else sum(xf2) end xfh2 from (select kcdm,kcmc,kcxz,cj,xf,decode(floor(McjN/60),1,xf) xf1,decode(floor(McjN/60),0,xf) xf2 from (select a.*,b.xymc from (select a.*,b.kkbmdm from (select xn,xq,xkkh,xh,xm,kcmc,qzxs,xf,cj,zscj,bz,xgsj,xgs,cxbj,tzf,tzfjd,kcdm,pscj,qmcj,sycj,bkcj,cxcj,kcxz,tj,tjbz,cxxnxq,qzcj,kcgs,fxbj,jf,xsqr,sfkc,ysbkcj,McjN,McxcjN,zpZ,bkcjZ,cxcjZ,cxcj1Z,cxcj2Z,cxcj3Z,cxcj4Z,cxcj5Z,cxcj1,cxcj2,cxcj3,cxcj4,cxcj5,McjX,McxcjX,McjzPN,jycj,MjyN,MjycjN,MjybkcjN,MjycxcjN,MjycxbkcjN ,(case when (select x.kcdm from wjdszb x where x.kcdm=substr(a.xkkh,case when instr(a.xkkh,'-',1,3)<>0 then instr(a.xkkh,'-',1,3) else length(a.xkkh)+1 end+1,case when instr(a.xkkh,'-',1,4)<>0 then instr(a.xkkh,'-',1,4) else length(a.xkkh)+1 end-(case when instr(a.xkkh,'-',1,3)<>0 then instr(a.xkkh,'-',1,3) else length(a.xkkh)+1 end+1))) is null then (case when ((select x.mc from cjlrbzb x where (','||a.bz||',' like '%,'||x.mc||',%' or ','||a.cj||',' like '%,'||x.mc||',%') and x.sfwjd='是') is null) then to_char( ( (case when McxcjN>=60 then ( select max(to_number(jd)) from (select substr(cj,1,case when instr(cj,'-',1,1)<>0 then instr(cj,'-',1,1) else length(cj)+1 end-(1)) as qsd,substr(cj,case when instr(cj,'-',1,1)<>0 then instr(cj,'-',1,1) else length(cj)+1 end+1,case when instr(cj,'-',1,2)<>0 then instr(cj,'-',1,2) else length(cj)+1 end-(case when instr(cj,'-',1,1)<>0 then instr(cj,'-',1,1) else length(cj)+1 end+1)) as jsd,jd from bkcxjddzb where lb='重修' and cj like '%-%') a where to_number(qsd)<=McxcjN and to_number(jsd)>McxcjN ) when bkcjZ>=60 then ( select max(to_number(jd)) from (select substr(cj,1,case when instr(cj,'-',1,1)<>0 then instr(cj,'-',1,1) else length(cj)+1 end-(1)) as qsd,substr(cj,case when instr(cj,'-',1,1)<>0 then instr(cj,'-',1,1) else length(cj)+1 end+1,case when instr(cj,'-',1,2)<>0 then instr(cj,'-',1,2) else length(cj)+1 end-(case when instr(cj,'-',1,1)<>0 then instr(cj,'-',1,1) else length(cj)+1 end+1)) as jsd,jd from bkcxjddzb where lb='补考' and cj like '%-%') a where to_number(qsd)<=bkcjZ and to_number(jsd)>bkcjZ ) else to_number( ( select max(to_number(jd)) from (select substr(cj,1,case when instr(cj,'-',1,1)<>0 then instr(cj,'-',1,1) else length(cj)+1 end-(1)) as qsd,substr(cj,case when instr(cj,'-',1,1)<>0 then instr(cj,'-',1,1) else length(cj)+1 end+1,case when instr(cj,'-',1,10)<>0 then instr(cj,'-',1,10) else length(cj)+1 end-(case when instr(cj,'-',1,1)<>0 then instr(cj,'-',1,1) else length(cj)+1 end+1)) as jsd,jd from jddzb where cj like '%-%') a where to_number(qsd)<=ZpZ and to_number(jsd)>ZpZ )) end ) *(case when (select max(to_number(nvl(z.kcqzxs,1))) from kcxzdmb Z where a.kcxz=Z.kcxzmc) is null then 1 else (select max(to_number(nvl(z.kcqzxs,1))) from kcxzdmb Z where a.kcxz=Z.kcxzmc) end) )) else '' end) else '' end) jd ,case when McxcjX is not null then '*' else '' end dcxbj,cxdtcj,case when bkcj is not null then '*' else '' end bkcjbj from ( select a.*,case when McjN=zpZ then cj when McjN=bkcjZ then bkcj||'' when (McjN=cxcjZ and cxcj is not null) then cxcj||'' when (McjN=cxcj1Z and cxcj1 is not null) then cxcj1||'' when (McjN=cxcj2Z and cxcj2 is not null) then cxcj2||'' when (McjN=cxcj3Z and cxcj3 is not null) then cxcj3||'' when (McjN=cxcj4Z and cxcj4 is not null) then cxcj4||'' when (McjN=cxcj5Z and cxcj5 is not null) then cxcj5||'' end McjX, case when (McjN=cxcjZ and cxcj is not null) then cxcj||'' when (McjN=cxcj1Z and cxcj1 is not null) then cxcj1||'' when (McjN=cxcj2Z and cxcj2 is not null) then cxcj2||'' when (McjN=cxcj3Z and cxcj3 is not null) then cxcj3||'' when (McjN=cxcj4Z and cxcj4 is not null) then cxcj4||'' when (McjN=cxcj5Z and cxcj5 is not null) then cxcj5||'' end McxcjX from (select a.*, case when pscjN is null then 0 else to_number(pscjN) end pscjZ, case when qmcjN is null then 0 else to_number(qmcjN) end qmcjZ, case when sycjN is null then 0 else to_number(sycjN) end sycjZ, case when zpN is null then 0 else to_number(zpN) end zpZ, case when bkcjN is null then 0 else to_number(bkcjN) end bkcjZ, case when cxcjN is null then 0 else to_number(cxcjN) end cxcjZ, case when cxcj1N is null then 0 else to_number(cxcj1N) end cxcj1Z, case when cxcj2N is null then 0 else to_number(cxcj2N) end cxcj2Z, case when cxcj3N is null then 0 else to_number(cxcj3N) end cxcj3Z, case when cxcj4N is null then 0 else to_number(cxcj4N) end cxcj4Z, case when cxcj5N is null then 0 else to_number(cxcj5N) end cxcj5Z, case when bybkcjN is null then 0 else to_number(bybkcjN) end bybkcjZ, greatest(case when zpN is null then 0 else to_number(zpN) end,case when bkcjN is null then 0 else to_number(bkcjN) end,case when cxcjN is null then 0 else to_number(cxcjN) end, case when cxcj1N is null then 0 else to_number(cxcj1N) end,case when cxcj2N is null then 0 else to_number(cxcj2N) end,case when cxcj3N is null then 0 else to_number(cxcj3N) end ,case when cxcj4N is null then 0 else to_number(cxcj4N) end,case when cxcj5N is null then 0 else to_number(cxcj5N) end ) McjN, least(case when zpN is null then 0 else to_number(zpN) end,case when bkcjN is null then 0 else to_number(bkcjN) end,case when cxcjN is null then 0 else to_number(cxcjN) end, case when cxcj1N is null then 0 else to_number(cxcj1N) end,case when cxcj2N is null then 0 else to_number(cxcj2N) end,case when cxcj3N is null then 0 else to_number(cxcj3N) end ,case when cxcj4N is null then 0 else to_number(cxcj4N) end,case when cxcj5N is null then 0 else to_number(cxcj5N) end ) MincjN, greatest(to_number('0'||bkcjN),to_number('0'||zpN) ) McjzPN, greatest(case when cxcjN is null then 0 else to_number(cxcjN) end, case when cxcj1N is null then 0 else to_number(cxcj1N) end,case when cxcj2N is null then 0 else to_number(cxcj2N) end,case when cxcj3N is null then 0 else to_number(cxcj3N) end ,case when cxcj4N is null then 0 else to_number(cxcj4N) end,case when cxcj5N is null then 0 else to_number(cxcj5N) end ) McxcjN ,least(nvl(upper(jycj),'W'),nvl(upper(MjycxcjN),'W')) MjycjN ,least(nvl(upper(jybkcj),'W'),nvl(upper(MjycxbkcjN),'W')) MjybkcjN ,least(nvl(upper(jycj),'W'),nvl(upper(MjycxcjN),'W'),nvl(upper(jybkcj),'W'),nvl(upper(MjycxbkcjN),'W')) MjyN from (select cjb.*, case when (select dycj from cjdzb where cj=cjb.pscj) is null then cjb.pscj else (select to_char(dycj) from cjdzb where cj=cjb.pscj) end pscjN, case when (select dycj from cjdzb where cj=cjb.qmcj) is null then cjb.qmcj else (select to_char(dycj) from cjdzb where cj=cjb.qmcj) end qmcjN, case when (select dycj from cjdzb where cj=cjb.sycj) is null then cjb.sycj else (select to_char(dycj) from cjdzb where cj=cjb.sycj) end sycjN, case when (select dycj from cjdzb where cj=cjb.cj) is null then cjb.cj else (select to_char(dycj) from cjdzb where cj=cjb.cj) end zpN, case when (select dycj from cjdzb where cj=cjb.bkcj) is null then cjb.bkcj else (select to_char(dycj) from cjdzb where cj=cjb.bkcj) end bkcjN, case when (select dycj from cjdzb where cj=cjb.cxcj) is null then cjb.cxcj else (select to_char(dycj) from cjdzb where cj=cjb.cxcj) end cxcjN, case when (select dycj from cjdzb where cj=cjb.cxcj1) is null then cjb.cxcj1 else (select to_char(dycj) from cjdzb where cj=cjb.cxcj1) end cxcj1N, case when (select dycj from cjdzb where cj=cjb.cxcj2) is null then cjb.cxcj2 else (select to_char(dycj) from cjdzb where cj=cjb.cxcj2) end cxcj2N , case when (select dycj from cjdzb where cj=cjb.cxcj3) is null then cjb.cxcj3 else (select to_char(dycj) from cjdzb where cj=cjb.cxcj3) end cxcj3N, case when (select dycj from cjdzb where cj=cjb.cxcj4) is null then cjb.cxcj4 else (select to_char(dycj) from cjdzb where cj=cjb.cxcj4) end cxcj4N, case when (select dycj from cjdzb where cj=cjb.cxcj5) is null then cjb.cxcj5 else (select to_char(dycj) from cjdzb where cj=cjb.cxcj5) end cxcj5N, case when (select dycj from cjdzb where cj=cjb.bybkcj) is null then cjb.bybkcj else (select to_char(dycj) from cjdzb where cj=cjb.bybkcj) end bybkcjN from (select xn,xq,xkkh,xh,xm,kcmc,qzxs,xf,cj,zscj,bz,xgsj,xgs,cxbj,tzf,tzfjd,kcdm,pscj,qmcj,sycj,bkcj,cxcj,kcxz,tj,tjbz,cxxnxq,qzcj,kcgs,fxbj,jf,xsqr,jd,cxcj1,cxcj2,cxcj3,cxcj4,cxcj5,cxdtcj,jycj,jybkcj,MjycxcjN,MjycxbkcjN,bybkcj,sfkc,ysbkcj from cjb_3) cjb ) a) a ) a ) a,kcdmb b where a.xh='0407100522' and (sfkc is null or sfkc<>'否') and substr(a.xkkh,case when instr(a.xkkh,'-',1,3)<>0 then instr(a.xkkh,'-',1,3) else length(a.xkkh)+1 end+1,case when instr(a.xkkh,'-',1,4)<>0 then instr(a.xkkh,'-',1,4) else length(a.xkkh)+1 end-(case when instr(a.xkkh,'-',1,3)<>0 then instr(a.xkkh,'-',1,3) else length(a.xkkh)+1 end+1))=b.kcdm(+) order by a.xkkh) a,xydmb b where a.kkbmdm=b.xydm(+) order by xn,xq,kcxz)) group by kcxz) b on a.kcxzmc=b.kcxz union all select '99','合计',sum(xfyq),sum(xfh1),sum(xfh2),sum(xfc) from (select case when a.kcxzdm is null then '98' else a.kcxzdm end kcxzdm,a.kcxzmc,case when a.xfyq is null then 0 else to_number(a.xfyq) end xfyq ,b.xfh1,b.xfh2,to_number(to_number((case when a.xfyq is null then 0 else to_number(a.xfyq) end))-to_number(b.xfh1)) xfc from (select * from jxjhxfyqview where jxjhh=(select dqszj||zydm from xsjbxxb where xh='0407100522')) a left join (select kcxz,case when sum(xf1) is null then 0 else sum(xf1) end xfh1,case when sum(xf2) is null then 0 else sum(xf2) end xfh2 from (select kcdm,kcmc,kcxz,cj,xf,decode(floor(McjN/60),1,xf) xf1,decode(floor(McjN/60),0,xf) xf2 from (select a.*,b.xymc from (select a.*,b.kkbmdm from (select xn,xq,xkkh,xh,xm,kcmc,qzxs,xf,cj,zscj,bz,xgsj,xgs,cxbj,tzf,tzfjd,kcdm,pscj,qmcj,sycj,bkcj,cxcj,kcxz,tj,tjbz,cxxnxq,qzcj,kcgs
    nilai
        82
    nilai  
       2017-03-06 17:10:30 +08:00
    接楼上, 你以为这就完了,图样图森破, 我只帖了四分之一, V2EX 字数限制。
    zhuchaowe
        83
    zhuchaowe  
       2017-03-06 17:30:51 +08:00
    @nilai 卧槽 6 的飞起
    nilai
        84
    nilai  
       2017-03-06 17:58:56 +08:00
    @zhuchaowe 对了, 要看完整版,请移步 http://www.doc88.com/p-3367592493132.html
    Z1076
        85
    Z1076  
       2017-03-06 18:04:45 +08:00
    @nilai 66666666
    chaleaoch
        86
    chaleaoch  
    OP
       2017-03-06 18:36:12 +08:00
    @nilai 太牛逼了!!!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2594 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 04:23 · PVG 12:23 · LAX 20:23 · JFK 23:23
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.