1

我有一张包含预定付款和过去付款的表格,我需要找出在同一周内是否有针对同一用户/合同的任何两项费用。

select count(*) from charge as c1, charge as c2 
where c1.id_contract = c2.id_contract 
  and c1.status = 'SUCCESS' 
  and c2.status in ('SUCCESS', 'PENDING', 'WAITING') 
  and c1.id > c2.id and c2.due_time > (c1.due_time - interval 7 day);

我很难在 sqlalchemy 中重现此查询,主要是因为我找不到如何以与数据库无关的形式将 MySQL 的“间隔”转换为 SQLAlchemy。

到目前为止,我想出了这个,它可以翻译所有内容,但间隔:

db.session.query(Charge, OldCharge).filter(Charge.id_contract == OldCharge.id_contract, Charge.status=='WAITING', OldCharge.status.in_(('SUCCESS', 'PENDING')), Charge.id > OldCharge.id).count()

有任何想法吗?

4

2 回答 2

4

如果您只需要DAYs (这是默认间隔),那么只需将您的 SQL 重述为:

c2.due_time > ADDDATE(c1.due_time, - 7)

可以用 SA 术语写成:

filter(Charge.due_time > func.ADDDATE(OldCharge.due_time, -7))

如果您需要过滤不同的时间间隔类型(周、月、年),您可能需要编写自定义 SQL 构造编译器(有关详细信息,请参阅自定义 SQL 构造和编译扩展)。

于 2012-09-22T12:34:15.993 回答
4

因此,我最终编写了一个自定义 date_diff() 表达式:

class date_diff(expression.FunctionElement):
    type = Integer()
    name = 'age'

@compiles(date_diff, 'default')
def _default_date_diff(element, compiler, **kw):  # pragma: no cover
    return "DATEDIFF(%s, %s)" % (compiler.process(element.clauses.clauses[0]),
                                 compiler.process(element.clauses.clauses[1]),
                                 )
@compiles(date_diff, 'mysql')
def _my_date_diff(element, compiler, **kw):  # pragma: no cover
    return "DATEDIFF(%s, %s)" % (compiler.process(element.clauses.clauses[0]),
                                 compiler.process(element.clauses.clauses[1]),
                                 )

@compiles(date_diff, 'sqlite')
def _sl_date_diff(element, compiler, **kw):    # pragma: no cover
    return "julianday(%s) - julianday(%s)" % (compiler.process(element.clauses.clauses[0]),
                                              compiler.process(element.clauses.clauses[1]),
                                              )
于 2012-11-26T14:09:11.477 回答