1
sonice 2020-07-03 14:11:57 +08:00
这儿就震惊了?普普通通
|
2
BrettD 2020-07-03 14:12:35 +08:00 via iPhone 1
这一坨怕不是复制粘贴搭出来的😂
|
3
sunziren 2020-07-03 14:25:09 +08:00
............,√
............,× |
4
jswxg 2020-07-03 14:25:51 +08:00
格式化后看就清楚很多了。
SELECT a.* FROM ( SELECT a.* FROM ( SELECT a.* FROM ( SELECT a.* FROM ( SELECT a.* FROM ( SELECT PLATFORM_REQUEST_CODE AS platformRequestCode, AGGTEGATE_REQUEST_CODE AS aggtegateRequestCode, CREATE_TIME AS createTime, STATUS AS payStatus, MERCHANT_GENERATE_CODE AS platformCode , USER_CODE AS buyCode, CHANNEL_NO AS channelNo FROM tb_aggtegate_payment_request WHERE STATUS != '00' AND DEL_FLAG = 0 AND IS_VALID = 0 ORDER BY CREATE_TIME DESC ) a LEFT JOIN ( SELECT CHANNEL_REQUEST_CODE AS channelOrderCode, AGGTEGATE_REQUEST_CODE AS channelaggtegateRequestCode FROM tb_channel_send_report WHERE DEL_FLAG = 0 ) b ON a.aggtegateRequestCode = b.channelaggtegateRequestCode ) a LEFT JOIN ( SELECT MERCHANT_INFO_CODE, MERCHANT_INFO_NAME AS platformName FROM tb_merchant_info WHERE DEL_FLAG = 0 ) c ON c.MERCHANT_INFO_CODE = a.platformCode ) a LEFT JOIN ( SELECT PLATFORM_USER_CODE, MERCHANT_NAME AS merchantName FROM tb_user_info WHERE DEL_FLAG = 0 ) b ON a.buyCode = b.PLATFORM_USER_CODE ) a LEFT JOIN ( SELECT CHANNEL_CODE, CHANNEL_NAME AS channelName FROM tb_channel_info WHERE DEL_FLAG = 0 ) b ON a.channelNo = b.CHANNEL_CODE ) a LEFT JOIN ( SELECT AGGTEGATE_REQUEST_CODE, TIME_END AS payTime FROM tb_wxpay_order_business WHERE DEL_FLAG = 0 AND IS_VALID = 0 ) b ON a.aggtegateRequestCode = b.AGGTEGATE_REQUEST_CODE WHERE 1 = 1 |
5
aaronlam 2020-07-03 14:27:15 +08:00
这就震惊了,想当年我刚接触到我们公司计费系统的 SQL 代码时,整个人都不好了。
|
6
airplayxcom 2020-07-03 14:27:42 +08:00 1
1=1 就很灵性了
|
7
loading 2020-07-03 14:28:40 +08:00 via Android 1
@airplayxcom 1=1 是标准的拼接 sql 常用技巧
|
9
takemeaway 2020-07-03 14:31:55 +08:00
挺好的项目,就是写这个项目的人脑子太直了
|
11
luxinfl OP @takemeaway 话说不是不应该用这么多连接么,阿里巴巴开发手册上面还禁止使用连接
|
13
est 2020-07-03 14:38:40 +08:00 102
新人和老人的区别就是面对一坨屎山,新人会大吃一斤。老人会贤淑的避开最臭的那部分屎,然后灵巧的在保证屎山不垮的情况下把自己的屎再拉一层上去
|
14
cbasil 2020-07-03 14:39:05 +08:00
太复杂,join 多的查询建视图啊,
|
16
laminux29 2020-07-03 14:45:22 +08:00
DBA 不懂编程思维,不懂调试测试,写出 shi 一样的 SQL,很正常。
你受不了可以自己改。 |
18
rtp 2020-07-03 14:51:17 +08:00
这才哪到哪,我记得原来的公司,写统计方面的 sql,基本上都是一条语句几屏幕啊……
|
19
soulzz 2020-07-03 14:52:09 +08:00
牛皮 用 sql 语句写业务
估计真的是老开发才会干的蠢事 |
20
z960112559 2020-07-03 14:52:43 +08:00
@est 666
|
21
Vegetable 2020-07-03 14:54:03 +08:00
@airplayxcom 1=1 的确挺蛇皮的,我不喜欢,为了保证 where 后边不空添加一个 true,我不敢说这算是技巧,这算是补丁。
|
24
526326991 2020-07-03 15:00:18 +08:00
就这?
|
25
baozhuo 2020-07-03 15:00:41 +08:00 via iPhone
这就震惊了?你知道我当初实习的时候见到同事有一个功能,他写了一个接近 6000 行的存储过程的时候有多震惊吗?当时有幸在那个项目组,后来把分配给我的东西做完我就溜了,差点自闭了
|
29
leonardyang 2020-07-03 15:11:32 +08:00 1
从 sql 角度看还好吧,主要是写的可读性有点差,我很讨厌一屏都放不完的 sql 。关键是表结构是谁设计的,也是新人? join 多不多不就看表结构设计吗,按学校数据库课程教的那套范式必然一堆 join 啊,从设计时候就应该考虑冗余字段减少关联查询,没有对新人做的表设计做 review ?
|
30
luhe 2020-07-03 15:13:43 +08:00
弱弱的问一下,实际开发一般 sql 写多长...
|
32
xxlee 2020-07-03 15:14:57 +08:00
left join 取 a.*,这和取最里面那层 select a.* 有啥区别呢?最后再加一个 where 1=1 。。。。 实在无法吐槽
|
33
toesbieya 2020-07-03 15:17:55 +08:00
为啥会觉得写的没问题啊,这 5 层嵌套 `select` 有什么意义,和 `left join ... left join` 有什么区别
|
34
leonardyang 2020-07-03 15:21:03 +08:00
|
35
EricFuture 2020-07-03 15:23:40 +08:00
这个还才一屏不到,习惯就好了
|
36
pomelotea2009 2020-07-03 15:30:00 +08:00 via Android
这才 join 五次啊,不过嵌套的五次比较少见。所以开发要对业务有一定的了解,这种情况一般优先考虑把不可变字段做冗余,其次考虑为了取一两个字段要去 join 整个表的那一两个字段做冗余,即使该字段是可变的(当然表少数据量小无所谓)
|
37
xxlee 2020-07-03 15:33:34 +08:00 1
@leonardyang 他这种取法,和最里面那层 a.*是一样的
|
38
Xusually 2020-07-03 15:33:46 +08:00
不知道表结构,索引设置什么的。
单看 sql 问题似乎不是非常大 |
39
vxlol 2020-07-03 15:35:21 +08:00
这种程度的 SQL 就惊了。。
比这还夸张的在我以前待的一大型制造企业 ERP 系统里比比皆是~ 业务逻辑基本都在存储过程,随便拎一个就是几百上千行~ 尤其是财务模块,存储过程里面使用游标、递归、动态 SQL 、嵌套执行其它存储过程什么的,都见识过~ |
40
luxinfl OP @pomelotea2009 有三张表是基础信息,其实可以单独在代码里面查询后再匹配塞值。应该比连接三个表要快
|
43
magicdu 2020-07-03 15:38:37 +08:00 via Android
太年轻了,见过格式化都格式化不出来的 SQL 吗
|
46
leonardyang 2020-07-03 15:49:32 +08:00 1
@luxinfl 没看懂你的想法,所谓的匹配塞值不还是要遍历数据吗,莫非你是觉得自己用代码实现的“left join”比现代数据库的查询优化强?互联网公司要求少用 join 是用冗余字段实现的,不是靠在代码里再遍历一遍这种自欺欺人的方式。。。
|
47
Jrue0011 2020-07-03 15:49:41 +08:00
看起来中间有几个表目的是为了获取 xxx_name 给前端用于显示,如果在 name 允许用户修改即会改变的情况下,有什么好的做法吗。。。
|
48
nutting 2020-07-03 15:50:46 +08:00
sql 就这德性,很恶心的
|
49
winglight2016 2020-07-03 15:54:31 +08:00
这种子查询嵌套,我们一般用来人工减慢响应时间的,方便以后优化。。。
哈哈,开玩笑了,不过,子查询是需要尽量避免的吧,实在不行搞个动态视图也好呀。 |
50
Xusually 2020-07-03 15:55:27 +08:00
@luxinfl 光你贴出来的这个 sql 看没有明显的问题。
执行效率高还是低,肯定还是得看表结构以及索引的安排啊。 你可以实际执行一下,并且也查看一下这条 sql 在 db 的执行计划,看看情况。 光看 sql 本身没办法看出来效率有多低 |
51
est 2020-07-03 15:57:57 +08:00
这么多人点赞。怕了怕了。 😂
|
52
x66 2020-07-03 16:11:39 +08:00
我觉得还好吧,做互联网业务的人跟做 ERP/银行 /保险业务的人平常遇到到的业务复杂度不是同一个级别的。
|
53
LuciferGo 2020-07-03 16:19:53 +08:00
真这么写吧,要是每个关联都是命中索引问题倒也不大,丑是丑了点
|
55
Alexisused 2020-07-03 16:47:16 +08:00
之前用的报表系统一个报表只能写一个 sql, 最大的那个报表 SQL 写出来压缩之后还有 8K 字符,varchar2 存不下,后来没办法分成了 2 个报表..
|
56
zypy333 2020-07-03 16:53:08 +08:00
看到长 sql 就头大,楼主能贴出来优化后的 sql 吗
|
57
liprais 2020-07-03 17:00:02 +08:00 via iPhone
要喷也要看了执行计划做了 profile 再喷
阿里那手册看看就算了,毕竟 mysql 就那样 |
58
ReinerShir 2020-07-03 17:28:20 +08:00
一般是业务复杂,开发时间少,而且对性能没啥要求的后台功能才这么写
|
59
markyangd 2020-07-03 17:29:33 +08:00 via iPhone
见过 3000 行 sp 的人表示,你这个 sql 语句算小菜。
|
60
WytheHuang 2020-07-03 17:33:29 +08:00
这样格式化,能看了~
SELECT a.* FROM ( SELECT a.* FROM ( SELECT a.* FROM ( SELECT a.* FROM ( SELECT a.* FROM ( SELECT PLATFORM_REQUEST_CODE AS platformRequestCode, AGGTEGATE_REQUEST_CODE AS aggtegateRequestCode, CREATE_TIME AS createTime, STATUS AS payStatus, MERCHANT_GENERATE_CODE AS platformCode, USER_CODE AS buyCode, CHANNEL_NO AS channelNo FROM tb_aggtegate_payment_request WHERE STATUS != '00' AND DEL_FLAG = 0 AND IS_VALID = 0 ORDER BY CREATE_TIME DESC ) a LEFT JOIN ( SELECT CHANNEL_REQUEST_CODE AS channelOrderCode, AGGTEGATE_REQUEST_CODE AS channelaggtegateRequestCode FROM tb_channel_send_report WHERE DEL_FLAG = 0 ) b ON a.aggtegateRequestCode = b.channelaggtegateRequestCode ) a LEFT JOIN ( SELECT MERCHANT_INFO_CODE, MERCHANT_INFO_NAME AS platformName FROM tb_merchant_info WHERE DEL_FLAG = 0 ) c ON c.MERCHANT_INFO_CODE = a.platformCode ) a LEFT JOIN ( SELECT PLATFORM_USER_CODE, MERCHANT_NAME AS merchantName FROM tb_user_info WHERE DEL_FLAG = 0 ) b ON a.buyCode = b.PLATFORM_USER_CODE ) a LEFT JOIN ( SELECT CHANNEL_CODE, CHANNEL_NAME AS channelName FROM tb_channel_info WHERE DEL_FLAG = 0 ) b ON a.channelNo = b.CHANNEL_CODE ) a LEFT JOIN ( SELECT AGGTEGATE_REQUEST_CODE, TIME_END AS payTime FROM tb_wxpay_order_business WHERE DEL_FLAG = 0 AND IS_VALID = 0 ) b ON a.aggtegateRequestCode = b.AGGTEGATE_REQUEST_CODE WHERE 1 = 1 |
61
xhf1024 2020-07-03 17:40:53 +08:00
请问你们是基于自己的快速平台开发的嘛
|
62
kiracyan 2020-07-03 17:44:12 +08:00
看着恐怖而已 逻辑挺简单的
|
63
protectione055 2020-07-03 17:48:10 +08:00 via Android
@leonardyang ??原来学校教的那套范式都没用的吗?刚被数据库这套东西折磨完
|
64
lwlizhe 2020-07-03 17:51:23 +08:00
我是个客户端开发,接触的数据库查询没到这个量上
但是,之前有时被拉去开后端事故总结会的时候,时常听到子查询导致的种种慢查询……(我个人感觉子查询本身没啥问题,应该归属于子查询的查询索引问题吧,不知道这么说对不对) 记得后端老大还总结了一下数据库查询的几个注意点……可惜现在都忘了…… |
65
hello826 2020-07-03 17:54:07 +08:00
这个代码评审能过吗
|
67
KasonPasser 2020-07-03 18:31:06 +08:00
|
68
loading 2020-07-03 18:33:07 +08:00 via Android
@KasonPasser 用 1=1 可以满足洁癖在最后替换掉,你用 1 不好做。
|
70
Qusic 2020-07-03 20:14:33 +08:00 via iPhone
这叫为未来预留优化空间(
|
72
rockyou12 2020-07-03 20:20:12 +08:00
虽然这个 sql 本身就很屎,但 mysql 不支持 with 让这个 sql 更屎了。希望大家以后都不要再用 mysql,pg 真的好用很多……
|
74
rainysia 2020-07-03 22:50:19 +08:00
以前有个 oracle 的师傅...不写代码, 就直接写 SQL 给我。 大概平均一个 select 从开始到结束有个几千行吧。 中间各种生成, 变换, 计算, 叠加。
跟着写了两年。 各种黑魔法学的盆满钵满 |
75
justin2018 2020-07-03 22:53:06 +08:00
|
76
NoString 2020-07-04 01:46:14 +08:00
哈哈哈 这种在我们组大概会被枪毙
|
77
levelworm 2020-07-04 05:52:54 +08:00 via Android
话说如果是 BI 的话可以考虑用 dbt 这个工具
|
78
cozof 2020-07-04 06:48:19 +08:00 via iPhone
以前写存储过程或者看别人的存储过程很多都是上百行,不过这个 abcd 的表别名不怎么样。
|
79
collery 2020-07-04 09:29:33 +08:00
hive sql 经常这么写。连表查
|
80
lovecy 2020-07-04 14:35:17 +08:00
SELECT a.*
FROM ( SELECT a.* FROM ( SELECT a.* FROM ( SELECT a.* FROM ( SELECT a.* FROM ( SELECT PLATFORM_REQUEST_CODE AS platformRequestCode , AGGTEGATE_REQUEST_CODE AS aggtegateRequestCode , CREATE_TIME AS createTime , STATUS AS payStatus, MERCHANT_GENERATE_CODE AS platformCode , USER_CODE AS buyCode , CHANNEL_NO AS channelNo FROM tb_aggtegate_payment_request WHERE STATUS != '00' AND DEL_FLAG = 0 AND IS_VALID = 0 ORDER BY CREATE_TIME DESC ) `a` LEFT JOIN ( SELECT CHANNEL_REQUEST_CODE AS channelOrderCode, AGGTEGATE_REQUEST_CODE AS channelaggtegateRequestCode FROM tb_channel_send_report WHERE DEL_FLAG = 0 ) `b` ON a.aggtegateRequestCode = b.channelaggtegateRequestCode ) `a` LEFT JOIN ( SELECT MERCHANT_INFO_CODE, MERCHANT_INFO_NAME AS platformName FROM tb_merchant_info WHERE DEL_FLAG = 0 ) `c` ON c.MERCHANT_INFO_CODE = a.platformCode ) `a` LEFT JOIN ( SELECT PLATFORM_USER_CODE, MERCHANT_NAME AS merchantName FROM tb_user_info WHERE DEL_FLAG = 0 ) `b` ON a.buyCode = b.PLATFORM_USER_CODE ) `a` LEFT JOIN ( SELECT CHANNEL_CODE, CHANNEL_NAME AS channelName FROM tb_channel_info WHERE DEL_FLAG = 0 ) `b` ON a.channelNo = b.CHANNEL_CODE ) `a` LEFT JOIN ( SELECT AGGTEGATE_REQUEST_CODE, TIME_END AS payTime FROM tb_wxpay_order_business WHERE DEL_FLAG = 0 AND IS_VALID = 0 ) `b` ON a.aggtegateRequestCode = b.AGGTEGATE_REQUEST_CODE WHERE 1 = 1 |
81
lovecy 2020-07-04 14:51:19 +08:00
```
啊哈哈哈哈,没有效果啊,白格式化了大半天,貌似 markdown 语法也无效 ``` |
82
shakoon 2020-07-04 18:23:56 +08:00
说实话我没看懂这个拉屎人的目的,left join 一堆东西但最后都没有用到 join 得到的字段。
SELECT AA.PLATFORM_REQUEST_CODE AS PLATFORMREQUESTCODE, AA.AGGTEGATE_REQUEST_CODE AS AGGTEGATEREQUESTCODE, AA.CREATE_TIME AS CREATETIME, AA.STATUS AS PAYSTATUS, AA.MERCHANT_GENERATE_CODE AS PLATFORMCODE, AA.USER_CODE AS BUYCODE, AA.CHANNEL_NO AS CHANNELNO FROM TB_AGGTEGATE_PAYMENT_REQUEST AA LEFT JOIN TB_CHANNEL_SEND_REPORT BB ON BB.DEL_FLAG = 0 AND AA.AGGTEGATE_REQUEST_CODE = BB.CHANNELAGGTEGATEREQUESTCODE LEFT JOIN TB_MERCHANT_INFO CC ON CC.DEL_FLAG = 0 AND CC.MERCHANT_INFO_CODE = AA.MERCHANT_GENERATE_CODE LEFT JOIN TB_USER_INFO DD ON DD.DEL_FLAG = 0 AND AA.USER_CODE = DD.PLATFORM_USER_CODE LEFT JOIN TB_CHANNEL_INFO EE ON EE.DEL_FLAG = 0 AND AA.CHANNEL_NO = EE.CHANNEL_CODE LEFT JOIN TB_WXPAY_ORDER_BUSINESS FF ON FF.DEL_FLAG = 0 AND FF.IS_VALID = 0 AND AA.AGGTEGATE_REQUEST_CODE = FF.AGGTEGATE_REQUEST_CODE WHERE AA.STATUS != '00' AND AA.DEL_FLAG = 0 AND AA.IS_VALID = 0 ORDER BY AA.CREATE_TIME DESC |
83
shakoon 2020-07-04 18:33:17 +08:00
|
84
realpg 2020-07-05 00:35:13 +08:00
以前在一个公司招聘 PHP,有一个 JAVA 开发商业软件转过来的大佬。
面试题有一个数据库结构跟所要的查询结果格式比较蹩脚的题,基本考察就是性能考虑,这么进行交叉,循环设计 这个大佬拿笔记本摆弄了半天,非常牛逼的特意给我炫耀他接这题的方式,一条 2KB 的 SQL 语句拼接…… 那还是跑在笔记本的测试库下本身也就几十万数据量下,一个查询卡了能有 0.5 秒…… |
85
pydiff 2020-07-05 11:27:49 +08:00
是我的话我直接扔回给写的人,看着就觉得恶心
|