Python SQLAlchemy:选择多个表
我想优化我的数据库查询:Python SQLAlchemy:选择多个表,python,mysql,sql,sqlalchemy,Python,Mysql,Sql,Sqlalchemy,我想优化我的数据库查询: link_list = select( columns=[link_table.c.rating, link_table.c.url, link_table.c.donations_in], whereclause=and_( not_(link_table.c.id.in_( select( columns=[request_table.c.recipient],
link_list = select(
columns=[link_table.c.rating, link_table.c.url, link_table.c.donations_in],
whereclause=and_(
not_(link_table.c.id.in_(
select(
columns=[request_table.c.recipient],
whereclause=request_table.c.donator==donator.id
).as_scalar()
)),
link_table.c.id!=donator.id,
),
limit=20,
).execute().fetchall()
并尝试在一个查询中合并这两个选择:
link_list = select(
columns=[link_table.c.rating, link_table.c.url, link_table.c.donations_in],
whereclause=and_(
link_table.c.active==True,
link_table.c.id!=donator.id,
request_table.c.donator==donator.id,
link_table.c.id!=request_table.c.recipient,
),
limit=20,
order_by=[link_table.c.rating.desc()]
).execute().fetchall()
数据库架构如下所示:
link_table = Table('links', metadata,
Column('id', Integer, primary_key=True, autoincrement=True),
Column('url', Unicode(250), index=True, unique=True),
Column('registration_date', DateTime),
Column('donations_in', Integer),
Column('active', Boolean),
)
request_table = Table('requests', metadata,
Column('id', Integer, primary_key=True, autoincrement=True),
Column('recipient', Integer, ForeignKey('links.id')),
Column('donator', Integer, ForeignKey('links.id')),
Column('date', DateTime),
)
请求_表中有多个链接(捐赠者)指向链接_表中的一个链接。我想从link_表中获取尚未“请求”的链接
但这是行不通的。真的有可能吗,我想做什么?如果是,你会怎么做
提前非常感谢 您可能正在查找SQL
不存在的结构:
在:
首先,原始查询:
>>> print select(
... columns=[link_table.c.url, link_table.c.donations_in],
... whereclause=and_(
... not_(link_table.c.id.in_(
... select(
... columns=[request_table.c.recipient],
... whereclause=request_table.c.donator==5
... ).as_scalar()
... )),
... link_table.c.id!=5,
... ),
... limit=20,
... )
SELECT links.url, links.donations_in
FROM links
WHERE links.id NOT IN (SELECT requests.recipient
FROM requests
WHERE requests.donator = :donator_1) AND links.id != :id_1
LIMIT 20
并根据exists()重写:
我自己解决了这个问题。我需要一个左外联接,因为它是多对一关系。谢谢@ahojnnes:为了历史的目的,请在答案中公布你的解决方案。老实说,我的解决方案不是解决方案,因为最终我意识到它做了一些不同的事情。但是现在我达到了一个点,我认为这在连接中是不可能的——至少没有两个select的效率高。所以我还是会很高兴有答案的!如果您发布实际的查询本身,而不是生成某些查询的(sqlalchemy?)代码,将更容易帮助您;其他DBMS可能根本不会受益;例如,postgresql将始终计划“不在子选择中”作为反连接,其方式与计划“不存在”完全相同
>>> print select(
... columns=[link_table.c.url, link_table.c.donations_in],
... whereclause=and_(
... not_(exists().where(request_table.c.donator==5)),
... # ^^^^^^^^^^^^^^
... link_table.c.id!=5,
... ),
... limit=20,
... )
SELECT links.url, links.donations_in
FROM links
WHERE NOT (EXISTS (SELECT *
FROM requests
WHERE requests.donator = :donator_1)) AND links.id != :id_1
LIMIT 20