我们需要一个 SQL 服务器查询,在查询中为数量不断增长的变量生成 n 分位数,这些变量按各种排列组合进行组合。示例中包含了这部分的内容:
statement 1:
ntile(10) over (partition by MAUorALL, User_Type, fsi.Month_ID
order by Objects_Created) AS Ntile_Mon_Objects_Created,
statement 2:
ntile(10) over (partition by MAUorALL, User_Type, fsi.Month_ID, *Country*
order by Objects_Created) AS Ntile_Country_Objects_Created
statement 3:
ntile(10) over (partition by MAUorALL, User_Type, fsi.Month_ID, *User*_Type
order by Objects_Created) AS Ntile_UT_Objects_Created
您可以看到这些语句是相同的,只是在第二个和第三个语句中创建了 country 和 user type 这两个用 * 标注的列。因此,我们为 Objects_Created 这个变量在不同层次上获取分位数,并且我们还必须为这些变量的各种可能的排列组合获取分位数,例如:
statement 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 来执行这些变量的所有排列组合,那可能会使事情变得更容易。
2、解决方案
一个可行的解决方案是使用 SQLalchemy 中的 generate() 函数来生成所有可能的列值组合。generate() 函数允许我们在查询中使用一个子查询,该子查询生成一组值。我们可以使用这个函数来生成所有可能的列值组合,然后使用这些组合作为我们 PARTITION BY 子句中的分区键。
例如,我们可以使用以下代码生成所有可能的 MAUorALL 和 User_Type 的组合:
from sqlalchemy import func, select
combinations = (
select([MAUorALL, User_Type])
.distinct()
.subquery()
)
然后,我们可以使用 generate() 函数将这些组合作为我们 PARTITION BY 子句中的分区键。例如,我们可以使用以下代码来计算 Objects_Created 的分位数,并按 MAUorALL 和 User_Type 分区:
ntile_mon_objects_created = func.ntile(10).over(
partition_by=combinations.c.MAUorALL, combinations.c.User_Type,
order_by=Objects_Created
)
我们还可以使用 generate() 函数来生成所有可能的 MAUorALL、User_Type 和 Country 的组合。例如,我们可以使用以下代码来计算 Objects_Created 的分位数,并按 MAUorALL、User_Type 和 Country 分区:
ntile_country_objects_created = func.ntile(10).over(
partition_by=combinations.c.MAUorALL, combinations.c.User_Type, combinations.c.Country,
order_by=Objects_Created
)
这种解决方案使我们能够为大量变量生成分位数,而无需手动编码所有可能的排列组合。这可以为我们节省大量时间和精力,尤其是在处理大量变量时。
代码例子
以下是一个完整的代码例子,演示如何使用 SQLalchemy 来为各种可能的列值组合生成分位数:
from sqlalchemy import create_engine, Column, Integer, String, func
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
engine = create_engine('postgresql://user:password@host:port/database')
Session = sessionmaker(bind=engine)
session = Session()
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
MAUorALL = Column(String)
User_Type = Column(String)
Country = Column(String)
Objects_Created = Column(Integer)
combinations = (
select([User.MAUorALL, User.User_Type])
.distinct()
.subquery()
)
ntile_mon_objects_created = func.ntile(10).over(
partition_by=combinations.c.MAUorALL, combinations.c.User_Type,
order_by=User.Objects_Created
)
results = session.query(User, ntile_mon_objects_created).all()
for user, ntile in results:
print(user.MAUorALL, user.User_Type, user.Objects_Created, ntile)
这个例子首先创建一个 SQLalchemy 引擎并创建一个会话。然后,它定义了一个名为 User 的模型类,其中包含我们想要查询的列。接着,它使用 generate() 函数生成所有可能的 MAUorALL 和 User_Type 的组合。然后,它使用 ntile() 函数计算 Objects_Created 的分位数,并按 MAUorALL 和 User_Type 分区。最后,它运行查询并打印结果。