我目前在节点中使用postgres来查询与其帐户相关联的特定标记的所有用户(注意:我使用node-postgres):
query = 'SELECT tags.*, pl.email FROM admin.tags tags
LEFT JOIN gameday.player_settings pl
ON tags.player_id = pl.id
WHERE tags.tag = $1'
client.query(
query,
[tagName],
function(err, results) {
...
然后将 [tagName]
传递给WHERE
子句。
我打算做的是用未知数量的标签进行查询,并返回拥有与其帐户相关联的所有标签的所有用户。所以我不想[tagName]
而是传递未知长度的数组[tagNames]
,而是我不知道如何实现这一目标。
答案 0 :(得分:2)
你需要向后转动问题。而不是:
哪些用户拥有所有这些标记,您需要询问哪些用户没有中的一个或多个这些标记。这是双重否定。
您还需要一种传递标记集的方法。如果客户端语言绑定支持它,那么执行此操作的最佳方法是作为数组值查询参数。如果客户端绑定不支持数组值参数,那么您将需要动态SQL。
一种表述可能是(未经测试,因为您没有提供样本架构和数据):
SELECT pl.email
FROM gameday.player_settings pl
WHERE NOT EXISTS (
SELECT 1
FROM unnest(?) AS wanted_tags(tag)
LEFT JOIN admin.tags tags
ON tags.tag = wanted_tags.tag
WHERE tags.player_id = pl.id
AND wanted_tags.tag IS NULL
);
对IS NULL
执行左连接和过滤称为左反连接。它保持左连接条件不匹配的行。因此,在这种情况下,只有当没有与此播放器关联的匹配标记时,我们才会保留wanted_tags
数组中的标记。如果剩下任何标记,WHERE NOT EXISTS
将返回false,因此排除了播放器。
双重思考,不是吗?这样 test 很容易犯错误。
这里?
应该是您的编程语言PostgreSQL数据库绑定的查询参数占位符。我不知道node.js是什么。这仅在您可以将数组作为节点中的查询参数传递时才有效。如果没有,您将不得不使用动态SQL生成ARRAY['x','y','z']
表达式或(VALUES ('x'), ('y'), ('z'))
子查询。
P.S。如果可能,请提供示例架构和数据。 http://sqlfiddle.com/很方便。