2014-03-05 43 views
0

我們有一個sql服務器查詢,我們需要爲越來越多的變量生成ntiles,以便變量在各種排列中相互組合。下面是一個摘錄示範了我的意思:SQLalchemy:用於列值組合的所有排列的分位數

聲明1:

ntile(10) over (partition by MAUorALL, User_Type, fsi.Month_ID 
        order by Objects_Created) AS Ntile_Mon_Objects_Created, 

聲明2:

ntile(10) over (partition by MAUorALL, User_Type, fsi.Month_ID, *Country* 
      order by Objects_Created) AS Ntile_Country_Objects_Created 

聲明3:

ntile(10) over (partition by MAUorALL, User_Type, fsi.Month_ID, *User*_Type 
       order by Objects_Created) AS Ntile_UT_Objects_Created 

您可以看到報表的編制是除了第二個和第三個創建了斜體列「國家」和「用戶類型」之外。因此,我們採取ntiles在不同級別的特徵相同的變量「Objects_Created」,我們也必須採取ntiles這些變量的各種可能的排列,如:

聲明4:

ntile(10) over (partition by MAUorALL, User_Type, fsi.Month_ID, *Country, User_Type* 
      order by Objects_Created) AS Ntile_Country_UT_Objects_Created 

我們可以手動將這些排列編碼爲一個點,但如果我們可以使用sqlalchemy執行這些變量的所有排列,它可能會使事情變得更容易。有沒有人有我可以重新使用的例子?

感謝您的幫助!

+0

發生了什麼事?自從上次使用SA以來,似乎有一個新的過程,貢獻者正在編輯我的代碼 - 我猜可讀性。謝謝你。你還提供我錯過的答案嗎? – ouonomos

回答

0

我不知道fsi如何與其他列,但假設所有的數據都是在一個模型中(這是很容易與sqlalchemy查詢擴展)象下面這樣:

class User(Base): 
    __tablename__ = 't_users' 
    id = Column(Integer, primary_key=True) 
    MAUorALL = Column(String) 
    User_Type = Column(String) 
    Country = Column(String) 
    Month_ID = Column(Integer) 
    Objects_Created = Column(Integer) 

任務通過簡單的完成用於創建查詢的itertools.permutations(或itertools.combinations,取決於您想實現的目標)的用法。下面的代碼會生成User表的查詢,其中包含各種ntiles。我認爲閱讀代碼就足夠了解正在發生的事情:

# configuration: {label: Column} 
column_labels = { 
     'Country': User.Country, 
     'UT': User.User_Type, 
     } 

def get_ntile(additional_columns=None): 
    """ @return: sqlalchemy expression for selecting a given ntile() using 
    predefined as well as *additional* columns. 
    """ 
    partition_by = [ 
     User.MAUorALL, 
     User.User_Type, 
     User.Month_ID, 
     ] 
    label = "Ntile_Objects_Created" 
    if additional_columns: 
     lbls = [] 
     for col_name in additional_columns: 
      col = column_labels[col_name] 
      partition_by.append(col) 
      lbls.append(col_name) 
     label = "Ntile_{}_Objects_Created".format("_".join(lbls)) 
    xprs = over(
      func.ntile(10), 
      partition_by = partition_by, 
      order_by = User.Objects_Created, 
      ).label(label) 
    return xprs 

def get_query(additional_columns=['UT', 'Country']): 
    """ @return: a query object which selects a User with additional ntiles 
    for predefined columns (fixed) and all possible permutations of 
    *additional_columns* 
    """ 
    from itertools import permutations#, combinations 
    tiles = [get_ntile(comb) 
      for r in range(len(additional_columns) + 1) 
      for comb in permutations(additional_columns, r) 
      ] 
    q = session.query(User, *tiles) 
    return q 

q = get_query() 
print [_c["name"] for _c in q.column_descriptions] 
# >>> ['User', 'Ntile_Objects_Created', 'Ntile_UT_Objects_Created', 'Ntile_Country_Objects_Created', 'Ntile_UT_Country_Objects_Created', 'Ntile_Country_UT_Objects_Created'] 

for tile in q.all(): 
    print tile 
+0

非常感謝範。我會試試看 - 我希望這能夠完成工作。我會評論它如何發展。 – ouonomos