我的表格下面是
目标表:
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)进行划船(interest_id 3),骑自行车(interest_id 4)和钓鱼(interest_id 6)
我如何在PgSQL中写这个?我阅读了关于联接的一些文档但是不知道处理兴趣中的一对多的最佳方法。用户在创建"目标"时可以输入1到3个兴趣点。
我需要匹配至少有一个类似兴趣的人,将来自坦帕之间的&到日期并且是1或2性别ID。
答案 0 :(得分:1)
首先要考虑三个问题:
daterange
类型而不是fromdate
和todate
。 PG有一些强大的日期范围运算符。因此,我假设您的表格会有一个dates daterange
列。longitude
和latitude
列转换为其他类型。您有两种选择:轻量级选择是使用内置point
类型,然后使用CREATE EXTENSION earthdistance
。在(lon,lat)单位中的两个点上使用<@>
运算符将在法定里程中给出距离。或者,更强大的PostGIS扩展可以与CREATE EXTENSION postgis
一起使用,然后您使用geography
类型作为经度和纬度。我将在这里使用第一个选项,因为它是最直接的,可能对你来说足够好。因此,您将拥有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;
此查询为您提供goal
表格中的所有匹配数据,每场比赛的一行,以及与比赛的距离和共同兴趣。
答案 1 :(得分:0)
试试这个:
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)