我在mysql下面的表格
以下是模型:
class cube(models.Model):
pid = models.IntegerField()
av = models.CharField(max_length=100)
sid = models.IntegerField()
st = models.IntegerField()
我想要了解的是,我想知道已经拥有的pid列表
(sid=1,st>=5) and (sid=2,st>=7)
根据截图,这应该会产生两个pid - 3214和3215。 pid 3213不满足条件,因此不会返回。
我正在尝试以下方法来实现我在View中的要求:
查看代码:
testq=(cube.objects.filter((Q(sid='1') & Q(srt_gte="5")) & (Q(sid='2') & Q(srt_gte="7")))
也尝试用lambda这种方式 -
input = [{"sid":1,"st":5},{"sid":2,"st":7}]
queries = [Q(sid=i['sid'], st__gte=i['st']) for i in input]
sid_query = reduce(lambda x, y: ________ , queries)
在上面的lambda中,我尝试使用case语句 (lambda x: 1如果查询别的话 0 )
queryset=cube.objects.values_list('pid').filter(sid_query).annotate('pid')
这不起作用:(
尝试了以下其他方式:
testq=cube.objects.filter(Q(sid__in=[1,2])& (Q(srt__gte=[5,7]))).annotate(c=Count('sid')).filter(c=2)
看起来这是错误的。
无法弄清楚如何根据我的要求获得结果。
List of pid's who has (sid=1,st>=5) and (sid=2,st>=7)
以下是该要求的SQL等效项:
select b.pid
from cube b
group by b.pid
having sum(case when (b.sid = 1) and (b.srt >= 5) then 1 else 0 end) > 0 AND
sum(case when (b.sid = 2) and (b.srt >= 7) then 1 else 0 end) > 0;
答案 0 :(得分:-1)
我相信你需要一个OR条件而不是AND,而你的第一个查询看起来几乎是正确的。您可以在Q对象中组合一些条件,使其更具可读性。
testq = cube.objects.filter(Q(sid='1', st_gte="5") | Q(sid='2', st_gte="7"))
AND条件不起作用,因为数据库中的单个记录不能同时具有sid=1
和sid=2
(这两个单独的记录)。然后,您可以使用testq.values_list('pid', flat=True)
来获取pid
值。
请注意,这会给你重复(你应该得到像[3214, 3214, 3215, 3215]
之类的东西),所以你需要转换成一个集合:
testq = set(testq) # note: this will evaluate your query
或在生成的查询集上调用.distinct()
。
testq = testq.distinct() # testq is still a QuerySet object.
另一种方法是下拉并使用raw
方法,如果您确定您的SQL查询返回了您想要的结果。
testq = cube.objects.raw(your_sql)
然后,您可以检查testq或迭代它,提取您需要的数据。请参阅docs for Performing raw queries
希望有所帮助。