我想知道如何将一个list / set / tuple从python(通过psycopg2)传递给postgres查询作为一列表。例如,如果列表是['Alice', 'Bob']
,我希望表格为:
| Temp |
+-------+
| Alice |
| Bob |
如果有人在阅读下面的部分后有其他建议来实现我的结果,那也没关系。
背景
我有一个SQL表,它有三列感兴趣:
ID | Members | Group
---+---------+----------
1 | Alice | 1
2 | Alice | 1
3 | Bob | 1
4 | Charlie | 1
5 | Alice | 2
6 | Bob | 2
7 | Alice | 3
8 | Bob | 4
9 | Charlie | 3
我想要一个包含特定成员组合的组表。请注意,成员可能在一个组中有多个项目(例如ID 1和2)。
对于['Alice']
的输入,我想要她所在的组(现在)以及仅包含她(唯一)的组,如下所示:
Group | Type
------+--------
1 | present
2 | present
3 | present
输入['Alice', 'Bob']
:
Group | Type
------+--------
1 | present
2 | unique
从阅读开始看起来我正在寻找here描述的关系划分,为此,我需要做原始问题,因为输入来自在python中处理的Web表单。同样,也欢迎替代解决方案。
答案 0 :(得分:3)
您需要创建一个子查询来创建成员计数,然后使用GROUP BY
语句执行简单的除数查询,但是针对IN static_set
子句而不是针对另一个表。因为这是python,所以你已经知道了静态集的大小。
我假设您已经有了一个数据库游标,该表名为GroupMembers
:
MEMBERSHIP_QUERY = '''
SELECT gm.group, mc.memberscount = %(len)s AS type
FROM groupmembers gm
JOIN (SELECT "group", COUNT(DISTINCT members) as memberscount
FROM groupmembers
GROUP BY "group") mc
ON gm.group = mc.group
WHERE gm.members IN %(set)s
GROUP BY gm.group, mc.memberscount
HAVING COUNT(DISTINCT gm.members) = %(len)s;
'''
def membership(members):
# obtain a cursor
for row in cursor.execute(MEMBERSHIP_QUERY, dict(len=len(members), set=members)):
yield dict(group=row[0], type=row[1])
因此无需使用TEMP表来执行此查询。
如果确实需要TEMP表用于其他目的,.executemany()
最容易插入一组行:
members = ['Alice', 'Bob']
cursor.execute('CREATE TEMP TABLE tmp_members (member CHAR(255)) ON COMMIT DROP;')
cursor.executemany('INSERT INTO tmp_members VALUES (%s);',
[(name,) for name in members])
注意.executemany()
需要一系列序列;每个条目都是一系列行数据,在这种情况下每个只包含一个名称。我生成一个单项元组列表来填充表格。
或者,您也可以使用映射序列并使用%(name)s
参数语法(因此行数据序列变为[dict(name=name) for name in members]
)。