如何为'where'子句中的项目返回一些默认值,这些项目在数据库表列中不匹配(不存在)

问题描述 投票:0回答:2

我有一个数据库表flight

pkid       from_city            to_city
1         Melbourne            BuenosAires
2         Budapest             Tokyo
3         Praslin              Anchorage

然后我有一些随机to_cities ['Paris','Tokyo','Madrid','Anchorage','im_not_on_earth']的列表/元组

现在使用sqlalchemy元数据我想要一个查询,如果存在则返回给定列表中匹配的pkidto_city,否则返回一些默认值,如果不存在则返回0

所以基本上我的输出应该给我每个城市的一些整数,我可以将输出中的每个整数映射到给定输入中的某个城市

以下任何示例输出都适用于我 -

{'Paris':0, 'Tokyo': 2, 'Madrid': 0, 'Anchorage': 3, 'im_not_on_earth': 0}

或者只是...... [0,2,0,3,0]

关于如何做到这一点的任何想法或建议?我以为我可以通过使用coalesce实现这一点。但是只有在db表中存在where子句中的值时才有效。不确定我对合并的理解是否正确。

编辑:**我不想迭代使用for循环和查询给定输入中的每个元素**

mysql python-3.x pandas sqlalchemy
2个回答
1
投票

您可以使用apply()并定义自己的函数,例如:

def get_id(x):

    find = flight[flight['to_city']==x]['pkid'].values
    match = find[0] if list(find) else 0
    return match

dict(zip(to_cities, pd.Series(to_cities).apply(get_id).values))

产量:

{'Paris': 0, 'Tokyo': 2, 'Madrid': 0, 'Anchorage': 3, 'im_not_on_earth': 0}

0
投票

您希望在提供的城市列表与航班表中的to_city列之间进行外部联接。鉴于数据库不知道您提供的城市列表,您必须使用循环连接应用程序代码。在您的示例代码中,每个to_city只出现在一个数据库行中,因此只映射到一个pkid。我假设多个不同的from_cities有可能将航班转到相同的to_city,因此您需要将每个to_city映射到pkids列表而不是单个值。因此,没有航班的to_city将由空列表而不是0表示。

您可以使用单个数据库查询检索匹配城市的列表,但是您需要一个循环来使用您提供的to_cities列表进行外部联接。以下代码应该实现您想要的。由于您还没有提供sqlalchemy代码,我假设您正在使用带有声明系统的ORM来定义您的表。

from collections import defaultdict

class Flight(Base):
    __tablename__ = 'flight'

    pkid = Column(Integer, primary_key=True)
    from_city = Column(String)
    to_city = Column(String)

to_cities = ['Paris','Tokyo','Madrid','Anchorage','im_not_on_earth']
query_result = session.query(Flight.to_city, Flight.pkid).filter(Flight.to_city.in_(to_cities)).all()
matching_cities = defaultdict(list)
for city, pkid in query_result:
    matching_cities[city] += [pkid]
result = {city: matching_cities.get(city, []) for city in to_cities}

鉴于您必须在应用程序代码中进行外部联接,因此值得考虑您的数据库设计。数据库将是一个更有效的地方。如果您有一个单独的表,其中包含与航班表具有外键关系的所有城市名称,那么您可以通过在查询中的城市和航班表之间执行外部联接来实现单个查询中的所需内容。

© www.soinside.com 2019 - 2024. All rights reserved.