Postgres独家标签搜索(Postgres exclusive tag search)

编程入门 行业动态 更新时间:2024-10-24 10:22:05
Postgres独家标签搜索(Postgres exclusive tag search)

我正在尝试返回与所有查询的“标记”相关联的用户关联的所有行。 我的表结构和所需的输出如下:

admin.tags: user_id | tag | detail | date 2 | apple | blah... | 2015/07/14 3 | apple | blah. | 2015/07/17 1 | grape | blah.. | 2015/07/23 2 | pear | blahblah | 2015/07/23 2 | apple | blah, blah | 2015/07/25 2 | grape | blahhhhh | 2015/07/28 system.users: id | email 1 | joe@test.com 2 | jane@test.com 3 | bob@test.com queried tags: 'apple', 'pear' desired output: user_id | tag | detail | date | email 2 | apple | blah... | 2015/07/14 | jane@test.com 2 | pear | blahblah | 2015/07/23 | jane@test.com 2 | apple | blah, blah | 2015/07/25 | jane@test.com

由于user_id 2与'apple'和'pear'相关联,因此返回她的'apple'和'pear'行中的每一行,并加入system.users以便还返回她的电子邮件。

我对如何正确设置这个postgresql查询感到困惑。 我已经用左反连接进行了多次尝试,但似乎无法获得所需的结果。

I'm trying to return all rows which are associated with a user who is associated with ALL of the queried 'tags'. My table structure and desired output is below:

admin.tags: user_id | tag | detail | date 2 | apple | blah... | 2015/07/14 3 | apple | blah. | 2015/07/17 1 | grape | blah.. | 2015/07/23 2 | pear | blahblah | 2015/07/23 2 | apple | blah, blah | 2015/07/25 2 | grape | blahhhhh | 2015/07/28 system.users: id | email 1 | joe@test.com 2 | jane@test.com 3 | bob@test.com queried tags: 'apple', 'pear' desired output: user_id | tag | detail | date | email 2 | apple | blah... | 2015/07/14 | jane@test.com 2 | pear | blahblah | 2015/07/23 | jane@test.com 2 | apple | blah, blah | 2015/07/25 | jane@test.com

Since user_id 2 is associated with both 'apple' and 'pear' each of her 'apple' and 'pear' rows are returned, joined to system.users in order to also return her email.

I'm confused on how to properly set up this postgresql query. I have made several attempts with left anti-joins, but cannot seem to get the desired result.

最满意答案

派生表中的查询为您提供具有所有指定标记的用户的用户ID,外部查询将为您提供详细信息。

select * from "system.users" s join "admin.tags" a on s.id = a.user_id join ( select user_id from "admin.tags" where tag in ('apple', 'pear') group by user_id having count(distinct tag) = 2 ) t on s.id = t.user_id;

请注意,此查询将包括同时具有您搜索的两个标记但只有至少具有指定的标记的用户。

使用您的示例数据,输出将是:

| id | email | user_id | tag | detail | date | user_id | |----|---------------|---------|-------|------------|------------------------|---------| | 2 | jane@test.com | 2 | grape | blahhhhh | July, 28 2015 00:00:00 | 2 | | 2 | jane@test.com | 2 | apple | blah, blah | July, 25 2015 00:00:00 | 2 | | 2 | jane@test.com | 2 | pear | blahblah | July, 23 2015 00:00:00 | 2 | | 2 | jane@test.com | 2 | apple | blah... | July, 14 2015 00:00:00 | 2 |

如果你想用grape排除行,只需where tag in ('apple', 'pear')添加where tag in ('apple', 'pear')到外部查询。

如果您只想要只有搜索过的标签而没有其他用户的用户(例如精确划分),您可以将派生表中的查询更改为:

select user_id from "admin.tags" group by user_id having sum(case when tag = 'apple' then 1 else 0 end) >= 1 and sum(case when tag = 'pear' then 1 else 0 end) >= 1 and sum(case when tag not in ('apple','pear') then 1 else 0 end) = 0

鉴于您的样本数据,这不会返回任何内容,因为用户2也有葡萄

示例SQL小提琴

The query in the derived table gets you the user ids for users that have all specified tags and the outer query gets you the details.

select * from "system.users" s join "admin.tags" a on s.id = a.user_id join ( select user_id from "admin.tags" where tag in ('apple', 'pear') group by user_id having count(distinct tag) = 2 ) t on s.id = t.user_id;

Note that this query would include users who have both tags that you search for but may have other too as long as they at least have the two specified.

With your sample data the output would be:

| id | email | user_id | tag | detail | date | user_id | |----|---------------|---------|-------|------------|------------------------|---------| | 2 | jane@test.com | 2 | grape | blahhhhh | July, 28 2015 00:00:00 | 2 | | 2 | jane@test.com | 2 | apple | blah, blah | July, 25 2015 00:00:00 | 2 | | 2 | jane@test.com | 2 | pear | blahblah | July, 23 2015 00:00:00 | 2 | | 2 | jane@test.com | 2 | apple | blah... | July, 14 2015 00:00:00 | 2 |

If you want to exclude the row with grape just add a where tag in ('apple', 'pear') to the outer query too.

If you want only users that have only the searched for tags and none other (eg. exact division) you can change the query in the derived table to:

select user_id from "admin.tags" group by user_id having sum(case when tag = 'apple' then 1 else 0 end) >= 1 and sum(case when tag = 'pear' then 1 else 0 end) >= 1 and sum(case when tag not in ('apple','pear') then 1 else 0 end) = 0

This would not return anything given your sample data as user 2 also has grape

Sample SQL Fiddle

更多推荐

本文发布于:2023-07-24 01:53:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1240142.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:标签   Postgres   exclusive   search   tag

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!