逻辑大量的写在 sql 语句里
source link: https://www.v2ex.com/t/835439
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
今天看了下同事写的代码,才发现他居然喜欢把大量的逻辑写在 sql 语句里,跟他讲了下,他说是以前同事教的,我认为这样写可读性实在太差了,但是他也不愿意听我的!想听听各位大佬怎么讲。 下面是一段 sql
SELECT
m.id,
m.menuname,
m.link,
m.parent_id,
m.menutype,
m.sort
-- CASE
-- WHEN pm.parent_id > 0 THEN
-- 1 ELSE 0
-- END hasChildren
FROM
menu m
-- LEFT JOIN ( SELECT DISTINCT parent_id FROM menu ) pm ON pm.parent_id = m.id
WHERE
m.is_deleted = 0
<if test="userId !=null and userId !=''">
and m.id in (SELECT DISTINCT
rm.menu_id
FROM
role2menu rm
LEFT JOIN role r ON r.id = rm.role_id
LEFT JOIN user2role ur ON ur.role_id = r.id
WHERE
rm.is_deleted = 0
AND ur.user_id = #{userId} )
</if>
ORDER BY
m.sort
这只牵扯到 3 张表,就这么多 left join ,我后面又去翻了翻 10 来次 left join 的也很多。
liuliangyz 10 小时 19 分钟前 1
我觉得这类人特别二
x86 10 小时 14 分钟前
efaun 10 小时 13 分钟前
levon 10 小时 11 分钟前 1
gimp 10 小时 10 分钟前
Jihua 10 小时 8 分钟前
est 10 小时 7 分钟前 9
最开始只有些教授发明了 B 树;
后来有穷 B 研究生把改成一个库可以被 C 语言调用
后来就有聪明商家包装成了一个 tcp 库拿出去卖钱
其次,后装市场为了迎合臭不要脸不懂技术分析师的需求,发明了 sql
没想到就火了。于是商家就把加上存储过程就是 RPC ,而且是 serverless 的小代码哦。insert/update/select/delete 对应 RESTful 的 CRUD ,sql 其实就是 GraphQL ,认证权限功能,分裤分婊功能,齐活了。
test3207 10 小时 7 分钟前 1
多次 query 的额外网络和 IO 开销需要考虑吗?
有没有好哥哥讲一讲
felixcode 10 小时 6 分钟前 via Android
nitmali 10 小时 3 分钟前 1
woodensail 10 小时 2 分钟前 6
所以一般是数据库先简单筛下,然后交给应用服务器做后续处理。
cando 9 小时 58 分钟前
有时候复杂需求就需要这种
注意项目统一使用、语句优化好执行速度合理、写点注释
murmur 9 小时 56 分钟前
kiracyan 9 小时 55 分钟前 1
SuperXRay 9 小时 53 分钟前
写一大坨业务代码就不恶心吗?就可读性好了吗?
yazinnnn 9 小时 52 分钟前
chenmobuys 9 小时 51 分钟前
Chad0000 9 小时 47 分钟前 via iPhone
yor1g 9 小时 43 分钟前 2
jeffxjh 9 小时 40 分钟前
ainyyy 9 小时 40 分钟前 2
kingwrcy 9 小时 33 分钟前
这个一次性能返回结果不是挺好?
你如果业务代码写也不见得别人能懂啥意思,sql 挺能表达你的业务的
leafre 9 小时 32 分钟前
join 最多 3 张表,再多不合理
james2013 9 小时 31 分钟前
当我看到有的统计 sql
各种 if 判断和 join,lefj join, 1 条 sql 语句竟然有 300 行+,看的都吐了
retrocode 9 小时 22 分钟前
你贴的这种写法有历史渊源的,有时候产品让加筛选,还特别急, 懒一点的人就是直接 sql 里改,然后丢 xml 上去更新
比如楼上说的 “这个功能明天就要”
早上提需求,中午问进度,第二天早上就要上线, 求稳定肯定是用改动最小的方法来的
不过恶心是真的恶心, 建议跑路, 我盲猜是政府项目
Paracosm 9 小时 19 分钟前
constantine008 9 小时 18 分钟前
jsjjdzg 9 小时 17 分钟前
aliveyang 9 小时 17 分钟前
muyiluop 9 小时 15 分钟前
比如:a 、b 两个表,b 中存了 a 的 id ,查询 b 表时有个条件是 a 中的 name 字段
不连表我能想到的方法是:根据 name 条件查询出 a 的 id ,然后通过 b.aid in 的方式来查询
wudaye 9 小时 11 分钟前
moxiaowei 9 小时 10 分钟前 2
acdfjelxe 9 小时 8 分钟前
fisherwei 9 小时 4 分钟前
wolfie 9 小时 3 分钟前 10
一边觉得同事菜,同事应该听我的。
发到 v2 发现自己菜,v2 所有人应该听我的。
quan01994 9 小时 3 分钟前
tabris17 9 小时 2 分钟前
liprais 9 小时 0 分钟前
InvincibleDream 8 小时 51 分钟前
oneisall8955 8 小时 46 分钟前 via Android
yeyang5211 8 小时 40 分钟前
join 十几张表的逻辑拆成代码也不好看 可读性照样差,你看他查了十几次数据库, 筛选了一堆数据
经常读着读着不知道原来的目的了.
一般遇到这种我的倾向是拆成 3 个左右小一点的 sql, 代码清晰了, sql 也好读了. 别人写的屎山就当没看到了 , 改这种东西折寿.
golangLover 8 小时 36 分钟前 via Android
deplivesb 8 小时 35 分钟前
ikas 8 小时 34 分钟前
当然..我看了下我们的代码是这样的....
select id,name,type
from sys_resource
where exists(
select 1
from sys_role_resource
where sys_resource.id = sys_role_resource.resource_id
and exists(
select sys_role.id
from sys_role
where sys_role_resource.role_id = sys_role.id
and sys_role.id in (
select sys_user_role.id from sys_user_role where sys_user_role.user_id = :userId
)
)
)
hidemyself 8 小时 26 分钟前
那种 ERP 和 OA 的项目里的 SQL ,才叫复杂
potatowish 8 小时 26 分钟前 via iPhone
楼上不少人说什么不够复杂的,显然是偏题
efaun 8 小时 24 分钟前 1
fanchenio 8 小时 22 分钟前
guaguaguaxia1 8 小时 4 分钟前
l00t 8 小时 0 分钟前
l00t 7 小时 59 分钟前
adoal 7 小时 55 分钟前 via iPhone
Baloneo 7 小时 49 分钟前 1
SELECT
DISTINCT
a.meter_name AS meter_name,
a.pro_name AS pro_name,
a.pro_energy_val AS pro_energy_val_default,
b.date AS date,
sum(b.ep_o) AS counts
FROM
(
SELECT
DISTINCT
sh.collect_code AS collect_code,
sh.address AS address,
pee.meter_id AS meter_id,
pee.meter_name AS meter_name,
%s
sum(sh.ep_o) AS ep_o
FROM organization art
LEFT JOIN organization arm ON arm.p_id=art.id
LEFT JOIN product_energy_exp pee ON arm.id=pee.meter_id OR art.id=pee.meter_id
LEFT JOIN area_collect ac ON ac.area_id=pee.meter_id
LEFT JOIN collect_config_modbus ccm ON ccm.id=ac.collect_id
INNER JOIN stat_hour sh ON sh.collect_code=ccm.collect_code AND sh.address=ccm.address
WHERE 1=1
%s
AND ac.calc = 1
AND sh.stat_time IS NOT NULL
AND ccm.collect_code IS NOT NULL
AND ccm.address IS NOT NULL
%s
) b
INNER JOIN
(
SELECT
DISTINCT
ccm.collect_code,
ccm.address,
pee.pro_energy_val,
pee.meter_id,
pee.meter_name,
pee.pro_energy_name AS pro_name
FROM organization art
LEFT JOIN organization arm ON arm.p_id=art.id
LEFT JOIN product_energy_exp pee ON arm.id=pee.meter_id OR art.id=pee.meter_id
LEFT JOIN area_collect ac ON pee.meter_id=ac.area_id
LEFT JOIN collect_config_modbus ccm ON ccm.id=ac.collect_id
WHERE 1=1
AND ac.calc = 1
%s
) a ON a.collect_code = b.collect_code
AND a.address = b.address
GROUP BY meter_name,pro_name,pro_energy_val,date
ORDER BY meter_name,pro_name
%s
```
whoisjohnlee 7 小时 34 分钟前
benzalus 7 小时 29 分钟前
曾经见识过一个面向存储过程的 php 项目,项目里每个 sql 百行起步。业务增长越快,死得越快
ytmsdy 7 小时 15 分钟前
有些大的存储过程,能打两张 A3 纸!
Leviathann 7 小时 14 分钟前 via iPhone
大量用到 clickhouse 之类的内置函数
jellywong 7 小时 13 分钟前
Leviathann 7 小时 8 分钟前 via iPhone
其他的逻辑都不会写 sql 里
dcsuibian 6 小时 56 分钟前
idblife 6 小时 54 分钟前 via iPhone
wonderfulcxm 6 小时 42 分钟前 via iPhone
楼主显然还停留在“我知道我是对的,如果你们说我错了,那我也是对的”上面。
notejava 6 小时 20 分钟前
onhao 6 小时 6 分钟前
https://wuhao.pw/archives/107/
https://wuhao.pw/archives/277/
估计很多同仁看到这一堆的 SQL ,都要劝我,逻辑判断, 函数 ,存储过程 最好都别写到 sql 里
不过说实话,用了是真爽阿, 少写很多业务代码。
至于坑同事,或者后来者。
不至于坑,合适,不影响 sql 执行效率的逻辑判断, 函数 ,存储过程 带来极致的效率,如果这些特性都怕维护,而不用,那要这些特性干什么?存在即有其合理的地方。
gengchun 5 小时 36 分钟前
c6h6benzene 5 小时 23 分钟前 via iPhone
xy90321 4 小时 50 分钟前 via iPhone
Cbdy 4 小时 30 分钟前 via Android
night98 4 小时 15 分钟前
1.数据量小,稍微有点要求的开发都会直接加载到内存
2.关联性弱,除了 user 和 role 的关联表数据量较大需要放到数据库查,其他的都可以直接走缓存查
综上所述你和楼主贴出来的 sql 都一般般
night98 4 小时 11 分钟前
Elietio 3 小时 49 分钟前
chineselittleboy 3 小时 39 分钟前 via Android
movieatravelove 3 小时 24 分钟前 via Android
IvanLi127 2 小时 53 分钟前 via Android
wangritian 1 小时 59 分钟前
wanacry 1 小时 18 分钟前 via iPhone
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK