PostgreSQL:返回一个表中的所有行,并与另一个表中的行连接
对于表foo中的每一行,我希望将其与表栏中的一行连接起来。 条形图中的行与foo中的行同名,且最新日期早于foo中的日期 例如: 食用鱼: 渔民与捕鱼日期有关,例如,渔民捕鱼的时间 表诱饵: 渔夫与诱饵有关,例如渔夫试图用什么来捕鱼 它们可能是这样的: 鱼类:PostgreSQL:返回一个表中的所有行,并与另一个表中的行连接,postgresql,join,postgresql-9.1,Postgresql,Join,Postgresql 9.1,对于表foo中的每一行,我希望将其与表栏中的一行连接起来。 条形图中的行与foo中的行同名,且最新日期早于foo中的日期 例如: 食用鱼: 渔民与捕鱼日期有关,例如,渔民捕鱼的时间 表诱饵: 渔夫与诱饵有关,例如渔夫试图用什么来捕鱼 它们可能是这样的: 鱼类: name | fishdate ----------------------------- bob | 2014-02-22 11:45:01 alice | 2014-02-22 12:45:02 alice
name | fishdate
-----------------------------
bob | 2014-02-22 11:45:01
alice | 2014-02-22 12:45:02
alice | 2014-02-22 12:50:04
bob | 2014-02-22 15:45:05
alice | 2014-02-22 14:42:50
诱饵:
name | date | bait
------------------------------------
bob | 2014-02-22 11:41:01 | worm
bob | 2014-02-22 11:42:01 | salomon
bob | 2014-02-22 11:47:01 | fakefish
alice | 2014-02-22 12:40:02 | salomon
alice | 2014-02-22 12:41:02 | worm
alice | 2014-02-22 12:49:04 | fakefish
alice | 2014-02-22 14:36:04 | salomon
bob | 2014-02-22 14:40:05 | worm
alice | 2014-02-22 14:41:04 | worm
alice | 2014-02-22 14:42:04 | salomon
alice | 2014-02-22 14:49:04 | fakefish
我想要的是渔夫目前使用的鱼饵:
name | fishdate | bait
-------------------------------------
bob | 2014-02-22 11:45:01 | salomon
alice | 2014-02-22 12:45:02 | worm
alice | 2014-02-22 12:50:04 | fakefish
bob | 2014-02-22 15:45:05 | worm
alice | 2014-02-22 14:42:50 | salomon
如何在PostgreSQL 9.1中做到这一点?一个选项是使用相关子查询 实际上,它为数据中的每一行运行SQL语句。在这种情况下,它从鱼身上获取每个日期,并从紧随其后的鱼饵中查找日期
SELECT
*
FROM
fishes
LEFT JOIN
baits
ON baits.name = fishes.name
AND baits.date = (SELECT MAX(date)
FROM baits AS lookup
WHERE lookup.date <= fishes.date
AND lookup.name = fishes.name
)
您可以使用:
以下是一个。Postgres支持:
请参阅这篇关于您的数据的文章
即使我自己这么说,它也相当优雅。是否只返回列名称、fishdate和bait?@SimonBosley-不,它返回两个表中的所有列,但这是一项我非常乐意留给OP的任务,从5个列中选择3个列并不困难。是的,他已经做到了这一点,你会认为他可以做到!此查询似乎有效,但运行时间非常长。即使只有30条记录,也需要几秒钟。基本上,鱼类包含300000条记录,而诱饵包含750000条记录。为了优化,可以肯定地说两个日期中的日期是相等的。@ManneTallmarken-如果baits表有一个关于name的索引,那么知道日期部分相同的date不会有什么区别。你有什么索引?
select name,fishdate,bait from
(
SELECT *, rank() over (partition by fishes.name,fishes.fishdate order by baits.date desc) ranked
from fishes inner join baits using (name)
where fishes.fishdate>=baits.date
) A
where ranked = 1
order by fishdate
select distinct
f.name,
fishdate,
last_value(bait) over (partition by f.name, fishdate order by date
rows between current row and unbounded following) bait
from fishers f
join baits b on b.name = f.name and date <= fishdate