我是flask和ORM的新手,我正在为我的学习编写一个示例应用程序。
我有这个型号:
class Timesheet(Base):
__tablename__ = 'Timesheet'
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey('user.id'), nullable='False')
start_date = Column(Date, nullable=False)
end_date = Column(Date, nullable=False)
total_time = Column(String(), nullable=False)
每个用户都需要提交每周的时间表,如果他错过了任何时间表,我们需要报告时间表。
例如 user1 时间表就像这样
Start_date | end_date
---------------------
2013-07-01 | 2013-07-08
2013-07-08 | 2013-07-15
2013-07-22 | 2013-07-29
我们需要报告错过的(2013-07-15 | 2013-07-22
)时间表
如何查询以在sqlalchemy中获得此结果?
答案 0 :(得分:3)
您所面临的问题在SQL世界中名称为 gap and islands 。你可以谷歌它(有关于这个主题的大量信息)或download从 SQL Server MVP Deep Dives 书中免费获得第5章,该书专门针对这个问题。从本章改编的第一个差距示例到SQLAlachemy如下:
t1 = aliased(Timesheet)
t2 = aliased(Timesheet)
subq1 = session.query(
func.min(t2.start_date)
).filter(
(t2.start_date > t1.end_date) &
(t2.user_id == t1.user_id)
).correlate(t1).as_scalar()
subq2 = session.query(t2).filter(
(t2.start_date == t1.end_date) &
(t2.user_id == t1.user_id)
).correlate(t1)
subq3 = session.query(
func.max(t2.start_date)
).filter(
t2.user_id == t1.user_id
).correlate(t1)
print session.query(
t1.user_id,
t1.end_date.label('start_date'),
subq1.label('end_date')
).filter(
(~subq2.exists()) &
(t1.end_date < subq3)
).all()
答案 1 :(得分:1)
SQL查询只能查找数据库中的数据,而不能查找丢失的数据,因此要有效地找到缺少的时间段,您需要稍微重新构建数据库。
我的建议是你用数据预填表。它或多或少会像这样工作:
在开始输入结束周的时间表之前,您运行的脚本会为该周的所有用户添加一个空的时间表。该脚本将添加时间表条目,例如,将total_time
字段设置为空。 (顺便说一句,我注意到这个字段是一个字符串,不应该是整数吗?)。
接下来,输入您从用户收到的时间表。这基本上只是用实际值更新空total_time
字段,因为脚本已经创建了所有时间表的记录。
现在,您可以使用查找空total_time
字段的简单查询找到缺少的时间表,并打印这些记录的开始/结束日期,如果有索引,SQL可以非常有效地执行在total_time
字段。
答案 2 :(得分:1)
我还要创建一个表格:在可能的过去和未来都会记录所有周的记录。
Weeks:
id
start_time
end_time
然后我应该编写一个查询,它将Timesheet与Weeks表连接,并按Timesheet过滤.start_dat为null。在这种情况下,您可能希望在开始日期和结束日期列上有索引。
BTW所有用户在同一个日历周都有相同的周开始和结束日期吗? 如果是 - 我将规范化数据库,并只添加Timesheet.week_id。