Sql peewee orm:使用外键连接三个表,计算中间表

Sql peewee orm:使用外键连接三个表,计算中间表,sql,postgresql,peewee,Sql,Postgresql,Peewee,我有以下peewee表/类(在postgres DB上)和虚线下面,这是我想要的示例 基本上,我是DB查询的新手,不知道如何构造它:我需要,给定一个天数列表(如['2015-01-01',…]),以获取每天的警报数量(如果有)作为每个服务的计数。希望下面的例子足够清楚 class Event(BaseModel): assessment = CharField(max_length = 4096) day = DateField() ongoing = BooleanFi

我有以下peewee表/类(在postgres DB上)和虚线下面,这是我想要的示例

基本上,我是DB查询的新手,不知道如何构造它:我需要,给定一个天数列表(如['2015-01-01',…]),以获取每天的警报数量(如果有)作为每个服务的计数。希望下面的例子足够清楚

class Event(BaseModel):
    assessment = CharField(max_length = 4096)
    day = DateField()
    ongoing = BooleanField()
    alertType = CharField(null = True)
    links = CharField(null = True, max_length = 4096)
    newLinks = CharField(null = True, max_length = 4096)
    startTime = TimeField()
    endTime = TimeField(null = True)

class Service(BaseModel):
    svcid = TextField(unique = True)
    name = TextField()

class Alert(BaseModel):
    alertId = CharField(unique = True, null = True)
    alertLink = CharField(unique = True, null = True)
    startTime = TimeField()
    endTime = TimeField(null = True)
    jcaLink = CharField(max_length = 4096, null = True)
    description = CharField(max_length = 4096)
    relatedNodes = CharField(null = True)
    customerName = CharField(null = True)
    jcaUrl = CharField(null = True)
    deviceName = CharField(null = True)
    event = ForeignKeyField(Event, related_name = 'alerts')
    service = ForeignKeyField(Service, related_name = 'alerts')
    hosted = CharField(default = None, null = True)

------------------------------------------------------------

Example: Event.id 1 has Event.day '2015-01-01'
         Event.id 2 has Event.day '2015-01-02'
         Service.id 1 has name "A"
         Service.id 2 has name "B"
         Alert.id 1 has Alert.event.id 1, Alert.service.id 1
         Alert.id 2 has Alert.event.id 2, Alert.service.id 2
         Alert.id 3 has Alert.event.id 2, Alert.service.id 1
         # end of db

If days is ['2015-01-01', '2015-01-02'], output should be like (not resembling, just broken up/organized somewhat like)
Service A
day 2015-01-01 
1 alert
day 2015-01-02
1 alert
-----------------
Service B
day 2015-01-01
1 alert
day 2015-01-02
0 alerts

这应该可以做到。我不确定您的模型是否添加了像
s.id
这样的列,但我想是这样的。您的开始时间是一个时间字段,所以我使用
date()
方法,所以我们只是比较日期部分

select s.name, date(a.start_time) as alert_date, count(s.name) as alerts
from alert a join service s on a.service_id = s.id
where date(a.start_time) in ('2015-01-01', '2015-01-02')
group by s.name, alert_date
请注意,执行分组依据时,必须在分组依据或聚合函数中使用所有选定字段。有很多方法可以解决这个问题,但是由于您需要的数据很少,所以不需要这样做,但是我假设
service.name
是唯一的

此外,如果您想按月份、年份等获取警报,您可以使用
extract
,如下所示:

select s.name, extract(month from a.start_time) as alert_month, 
extract(year from a.start_time) as alert_year, count(s.name) as alerts
from alert a join service s on a.service_id = s.id
where extract(year from a.start_time) = 2015
and extract(month from a.start_time) in (11, 12)
group by s.name, alert_month, alert_year

嘿,谢谢你的回答,但是Alert.startTime没有日期信息,只有“HH:MM”这样的时间。我摆弄了一下,得到了,生成的SQL大约是一半。我唯一缺少的是服务没有任何警报的天数的0。我知道,日期在event.day中。你在用什么?尝试将内部连接更改为左连接。我正在使用peewee orm:至于使用join.left\u OUTER更改连接,它不完全符合我的要求;它为天数添加空值,而不是警报计数。添加像
和“t3”这样的where子句。“day”不是空的
。where(Event.day.is_null(False))
有效吗?当您需要sql帮助时,在创建示例非常有用。