PostgreSQL:返回一个表中的所有行,并与另一个表中的行连接

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

对于表foo中的每一行,我希望将其与表栏中的一行连接起来。 条形图中的行与foo中的行同名,且最新日期早于foo中的日期

例如:

食用鱼: 渔民与捕鱼日期有关,例如,渔民捕鱼的时间

表诱饵: 渔夫与诱饵有关,例如渔夫试图用什么来捕鱼

它们可能是这样的:

鱼类:

 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