2011-05-09 55 views
1

有沒有辦法減少我的參數的重複?例如,時間模式重複4次,很難跟蹤大的查詢。在Python中編寫此SQL的更好方法

sql = ("SELECT IFNULL(b.inviters/COUNT(DISTINCT c.id),0),         " 
      "  FROM_UNIXTIME(c.registered_at, %s)           " 
      "FROM ( SELECT COUNT(1) AS inviters, joindate         " 
      "   FROM                 " 
      "    ( SELECT DISTINCT(y.id) AS inviters,        " 
      "       FROM_UNIXTIME(y.registered_at, %s) AS joindate   " 
      "     FROM user_invites z            " 
      "     INNER JOIN users y ON y.id = z.inviter_id      " 
      "     WHERE z.created_at >= %s          " 
      "    ) a                 " 
      "   GROUP BY a.joindate              " 
      "  ) b                   " 
      "INNER JOIN users c ON FROM_UNIXTIME(c.registered_at, %s) = b.joindate    " 
      "WHERE c.registered_at BETWEEN %s AND %s           " 
      "GROUP BY FROM_UNIXTIME(c.registered_at, %s)          " ) 

    args = ( timepattern, timepattern, datestart_int, timepattern, 
       datestart_int, dateend_int, timepattern) 

    cursor.execut(sql, args) 

    data = list(cursor.fetchall()) 

    cursor.close() 
    connection.close() 

回答

5

嘗試這種使用作爲參數dictionnary指定參數和使用顯式串插ARGS(即%(parameter_name)s):

sql = ("SELECT IFNULL(b.inviters/COUNT(DISTINCT c.id),0),         " 
      "  FROM_UNIXTIME(c.registered_at, %(timepattern)s)           " 
      "FROM ( SELECT COUNT(1) AS inviters, joindate         " 
      "   FROM                 " 
      "    ( SELECT DISTINCT(y.id) AS inviters,        " 
      "       FROM_UNIXTIME(y.registered_at, %(timepattern)s) AS joindate   " 
      "     FROM user_invites z            " 
      "     INNER JOIN users y ON y.id = z.inviter_id      " 
      "     WHERE z.created_at >= %(datestart_int)s          " 
      "    ) a                 " 
      "   GROUP BY a.joindate              " 
      "  ) b                   " 
      "INNER JOIN users c ON FROM_UNIXTIME(c.registered_at, %(timepattern)s) = b.joindate    " 
      "WHERE c.registered_at BETWEEN %(datestart_int)s AND %(dateend_int)s           " 
      "GROUP BY FROM_UNIXTIME(c.registered_at, %(timepattern)s)          " ) 

    args = { 
     "timepattern" : timepattern, 
     "datestart_int" : datestart_int, 
     "dateend_int" : dateend_int, 
    } 

    cursor.execute(sql, args) 
+0

您在編輯我的答案時添加了相同的內容,+1 :) – tmg 2011-05-09 09:01:45

4

你可以給ARGS如字典,然後用它在查詢像%(name)s例如

args = {'timepattern': timepattern, 'dateend_int': dateend_int} 
sql = ("SELECT IFNULL(b.inviters/COUNT(DISTINCT c.id),0),         " 
      "  FROM_UNIXTIME(c.registered_at, %(timepattern)s)           " 
      "FROM ( SELECT COUNT(1) AS inviters, joindate         " 
      "   FROM                 " 
      "    ( SELECT DISTINCT(y.id) AS inviters,        " 
      "       FROM_UNIXTIME(y.registered_at, %(timepattern)s AS joindate   " 
      "     FROM user_invites z            " 
      "     INNER JOIN users y ON y.id = z.inviter_id      " 
      "     WHERE z.created_at >= %(datestart_int)s          " 
      "    ) a                 " 
      "   GROUP BY a.joindate              " 
      "  ) b                   "
"INNER JOIN users c ON FROM_UNIXTIME(c.registered_at, %(timepattern)s) = b.joindate " "WHERE c.registered_at BETWEEN %(datestart_int)s AND %(datetart_int)s " "GROUP BY FROM_UNIXTIME(c.registered_at, %(timepattern)s)") cursor.execute(sql, args)

+0

我們絕對同意,+1;) – 2011-05-09 09:06:09

+0

Upvoted你的努力的答案。謝謝。 – super9 2011-05-09 09:19:29