select be.id, be.fullName1, be.workEmail
from employees as be
left join id_mapping as ci
on be.id = ci.user_id
where be.id like '%Steven%'
or be.fullName1 like '%Steven%'
or be.workEmail like '%Steven%'
or ci.new_id like '%Steven%'
group by be.id
1
lybcyd 2022-04-18 18:31:04 +08:00
django orm 和其他 orm 都不太一样,是不能直接使用 query builder 进行 join 的。后面的 group by 也不方便直接用,不过你这个语句 id 应该是 unique 的,又是非标准的 full group 语法,先忽略掉吧。
像这个语句,如果要尽可能使用 django orm 的推荐做法,应该建一个 IdMapping 的 model ,然后建立一对多或者一对一的关联关系(看你的业务逻辑)。这个关联关系可以直接当做一个 field 获取,也可以在条件里进行 lookup 。假设在 Employee model 里,这个关联关系叫做 mapping ,就可以直接使用 Employee.objects.filter(Q(id__icontains='Steven')|Q(fullName1__icontains='Steven')|Q(workEmail__icontains='Steven')|Q(mapping__new_id__icontains='Steven')).values('id','fullName1', 'workEmail') 来进行查询了。 看看官方文档是怎么定义的: https://docs.djangoproject.com/zh-hans/4.0/topics/db/models/#many-to-one-relationships https://docs.djangoproject.com/zh-hans/4.0/topics/db/queries/#lookups-that-span-relationships-1 如果 join 关系实在太复杂,用自带的很难拼接,那就干脆 raw 来实现。ORM 不是万能的,拼接一大堆复杂的条件还不如直接 sql 语句搞定。 |
2
roundgis 2022-04-18 18:34:01 +08:00 via Android
我用 orm 僅限 inner join
其他用法一律寫 sql 強行用 orm 有時候可讀性反而差 |
4
ila OP |
5
roundgis 2022-04-18 23:32:32 +08:00 via Android
|
6
neoblackcap 2022-04-19 01:31:24 +08:00
抱歉,Django ORM 没有 Left Join
|
7
ila OP |
8
ila OP @lybcyd 请问用这种方法应该怎么写呢
[left-join-django-orm]( https://stackoverflow.com/questions/21271835/left-join-django-orm) 仿写了几遍,卡住了,运行不成功 ``` from django.db.models.sql.datastructures import Join from django.db.models.fields.related import ForeignObject from django.db.models.options import Options from myapp.models import Ace from myapp.models import Subject jf = ForeignObject( to=Subject, on_delete=lambda: x, from_fields=[None], to_fields=[None], rel=None, related_name=None ) jf.opts = Options(Ace._meta) jf.opts.model = Ace jf.get_joining_columns = lambda: (("subj", "name"),) j=Join( Subject._meta.db_table, Ace._meta.db_table, 'T1', "LEFT JOIN", jf, True) q=Ace.objects.filter(version=296) q.query.join(j) print q.query ``` |
10
lybcyd 2022-04-19 12:06:07 +08:00
@ila 这个写法用了好多 orm 的内部结构,有点舍近求远了,不是很建议。
我简单写了个小 demo ,你看看能不能参考一下。 首先是 model 定义,关联关系是在这里定义的。不知道你的完整表结构,我就简单列了语句里出现的字段,其余的你自己补充一下吧。接下来可以进行查询了。 <script src="https://gist.github.com/lybcyd/b83084303657134d7cff52597ae315f9.js"></script> 打印这个 queryset ,可以看到生成的语句,我这里用的是 sqlite: SELECT "employees"."id", "employees"."fullName1", "employees"."workEmail" FROM "employees" LEFT OUTER JOIN "id_mapping" ON ("employees"."id" = "id_mapping"."user_id") WHERE ("employees"."id" LIKE %Steven% ESCAPE '\' OR "employees"."fullName1" LIKE %Steven% ESCAPE '\' OR "employees"."workEmail" LIKE %Steven% ESCAPE '\' OR "id_mapping"."new_id" LIKE %Steven% ESCAPE '\') |