Postgresql 使用表和子表上的条件进行搜索

Postgresql 使用表和子表上的条件进行搜索,postgresql,Postgresql,我有下面带有模式的表 目标表: id (int) user_id (int) location (string) from Google places latitude longitude gender (int) 1 male,2 female, 3 both fromdate (date) todate (date) 目标兴趣表: _id (int) goal_id (int) user_interest__id (int) 因此,用户输入一个目标。从2016-08-18到2016

我有下面带有模式的表

目标表:

id (int)
user_id (int)
location (string) from Google places
latitude 
longitude
gender  (int) 1 male,2 female, 3 both 
fromdate (date)
todate (date)
目标兴趣表:

_id (int)
goal_id (int)
user_interest__id (int)
因此,用户输入一个目标。从2016-08-18到2016-09-18,我将在美国佛罗里达州坦帕市寻找3名男性或女性,包括划船兴趣3名、自行车兴趣4名和钓鱼兴趣6名

我将如何在PgSQL中编写此代码?我读了一些关于连接的文档,但不知道处理一对多连接的最佳方法。用户在创建目标时可以输入1到3个兴趣

我需要匹配至少有1个类似兴趣的人,从开始到结束的日期之间将在坦帕,并且是1或2性别id的人。

尝试以下方法:

select
    g.user_id 
from
    goals g
join
    goal_interests gi on g.id = gi.goal_id 
where
    g.location = 'Tampa FL US' and
    g.fromdate >= '2016-08-18' and
    g.todate <= '2016-09-18' and
    g.gender in (1,2) and
    gi.user_interest__id in (3,4,6)

首先要考虑的三个问题:

应用程序的逻辑可能是首先将用户的目标和兴趣数据存储在表中,然后搜索匹配的目标。因此,下面的查询使用自连接和子查询来查找此类匹配项。 您应该使用daterange类型,而不是fromdate和todate。PG有一些强大的日期范围操作符。因此,我假设您的表将有一个dates daterange列。 你不应该在位置字符串上搜索,而应该在经度、纬度对上搜索,以及你的旅行者为了找到灵魂伴侣而愿意移动的最大距离上搜索。否则,圣彼得堡或克利尔沃特的一场完美的比赛将被忽视。为此,您还需要将单独的经度和纬度列转换为不同的类型。您有两种选择:轻量级选择是使用内置的点类型,然后创建延伸距离。在lon的两个点上使用操作员,lat单位将给出以法定英里为单位的距离。或者,功能更强大的PostGIS扩展可以与创建扩展PostGIS一起使用,然后您可以将地理类型用于经度和纬度。我将在这里使用第一个选项,因为它是最直接的,可能对您来说已经足够好了。因此,您将有一个loc point列,而不是经度和纬度。 然后,查询变成:

SELECT g2.*, g1.loc <@> g2.loc AS distance, i.interests
FROM goals g1  -- the traveler
JOIN goals g2  -- the soul mate
  ON (g2.loc <@> g1.loc) <= [[maximum distance in miles]]
 AND g2.dates && g1.dates -- dates must overlap (possibly partially)
 AND (g2.gender = 3 OR g2.gender = [[gender of user]])
JOIN (
  SELECT goal_id, array_agg(user_interest__id) AS interests
  FROM goal_interests
  WHERE user_interest__id IN (3, 4, 6) -- or whatever your interest are
  GROUP BY goal_id
) i ON i.goal_id = g2.id;

此查询将为您提供目标表中的所有匹配数据、每场比赛的一行,以及与比赛的距离和共同兴趣。

好吧,您不能将您的开发外包给此论坛。如果您自己不想阅读文档,请向某人付款。@Ehask use join,and抱歉,Laurenz他们让我比计划晚了4个月我收回了项目,并试图挽回一些我们支付的费用。我正在重写他们的大部分api代码……。这是为那些希望找到其他旅行者的旅行者而写的,不太喜欢约会,但我相信他们会习惯的。选择*从用户\目标\兴趣ugi左加入目标g在ugi上。目标\ id=g。\ id左加入用户u在g上。用户\ id=u。\ id在哪里位置='Zephyrhills,FL,“美国”和“2016-09-18”>=g.fromdate和“2016-08-18”