【问题标题】:Deal with empty arrays in WHERE clause在 WHERE 子句中处理空数组
【发布时间】:2016-11-12 17:37:59
【问题描述】:

我正在尝试使用接收名为date 的变量的函数执行查询:

def initial_query(date):

# Some code verifying the correctness of the date

query = """   SELECT some_fields
                FROM tableA A
          INNER JOIN tableB B on A.transaction_id = B.transaccion_id
               WHERE A.action_id in (1,2,3)
                 AND A.test = false
                 AND (maf.client_id = ANY(%(clients)s::bigint[]) OR maf.merchant_code = ANY(%(merchants)s::varchar[]))
                 AND maf.country_iso = ANY(%(countries)s)
                 AND maf.date >= '{date}'
                 """

return query.format(date=date)

main()内部,我使用initial_query(date)函数的方式如下:

cursor.execute(initial_query(starting_date), {'countries': countries, 'clients': client_ids,
                                                            'merchants': merchant_codes })

其中cursor 是一个psycopg2 游标,变量countries, clients, merchants 在某些情况下(但不是全部)可以是空列表。如果我向查询传递一个空列表,我将不会获得任何结果,因为任何行

 AND (maf.client_id = ANY(%(clients)s::bigint[]) OR maf.merchant_code = ANY(%(merchants)s::varchar[]))
 AND maf.pais_iso = ANY(%(countries)s)

总是会返回 false。所以我想知道是否有某种方法可以使用SQL代码来修改initial_query中的查询,以避免这些行总是返回false,因为传递给游标的任何列表都是空的。

【问题讨论】:

    标签: arrays postgresql python-2.7 psycopg2


    【解决方案1】:

    我解决了这个问题,添加了一个布尔变量来为每个案例提供两个不同的查询

    def initial_query(date, is_segment=False):
    
    # Some code verifying the correctness of the date
         if is_segment:
            query = """   SELECT some_fields
                            FROM tableA A
                      INNER JOIN tableB B on A.transaction_id = B.transaccion_id
                           WHERE A.action_id in (1,2,3)
                             AND A.test = false
                             AND (maf.client_id = ANY(%(clients)s::bigint[]) OR maf.merchant_code = ANY(%(merchants)s::varchar[]))
                             AND maf.date >= '{date}'
                     """
        else:
            query = """   SELECT some_fields
                            FROM tableA A
                      INNER JOIN tableB B on A.transaction_id = B.transaccion_id
                           WHERE A.action_id in (1,2,3)
                             AND A.test = false
                             AND maf.country_iso = ANY(%(countries)s)
                             AND maf.date >= '{date}'
                     """
        return query.format(date=date)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-24
      • 2011-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-15
      • 1970-01-01
      • 2013-12-22
      相关资源
      最近更新 更多