我有两张桌子,分别是tb1个号和tb2个号.tb2个通过名为tk_id的外键连接到tb1个.下面是我的两张桌子的外观

tb1

     Column      |            Type             | Collation | Nullable |                     Default                      
-----------------+-----------------------------+-----------+----------+--------------------------------------------------
 id              | integer                     |           | not null | nextval('tb2_id_seq'::regclass)
 created_at      | timestamp without time zone |           | not null | 
 modified_at     | timestamp without time zone |           | not null | 
 status          | double precision            |           | not null | 
 tk_id           | uuid                        |           | not null | 
 

tb2

     Column     |            Type             | Collation | Nullable | Default 
----------------+-----------------------------+-----------+----------+---------
 id             | uuid                        |           | not null | 
 created_at     | timestamp without time zone |           | not null | 
 modified_at    | timestamp without time zone |           | not null | 
 destination_id | uuid                        |           | not null | 
 source_id      | uuid                        |           | not null | 
 tk_id          | uuid                        |           | not null | 

Now I need to get all rows from tb1个 which has columns from both tb1个 and tb2个 when the tk_id value matches for both the rows.

这就是我try 过的:

select tb1.created_at, tb1.status, tb2.source_id, tb2.destination_id from tb1 
inner join tb2 on tb1.tk_id = tb2.tk_id where 
tb1.created_at > timezone('utc', now()) - interval '40 minutes';

但我排得太多了.通常在40min个间隔中,大约有800条记录,但在联接之后,我得到了大约100,000+条记录.

在一些阅读和几次try 之后,我对查询进行了一些更改,并设法将行减少到预期的行数.这是我现在的疑问

SELECT count(*) FROM tb1 LEFT OUTER JOIN (SELECT DISTINCT tk_id FROM tb2) t2 
ON tb1.tk_id = t2.tk_id where tb1.created_at > timezone('utc', now()) - 
interval '40 minutes';

But now I can't get the columns of tb2个 in my select query.

我做错了什么?

EDIT2: Sorry if I couldn't make this clearer earlier. The join condition should be based on the latest occurrence of tk_id of the right table. So for every row of left table (tb1个), it should match against the latest occurrence of tk_id of right table (tb2个) and fetch the right table's columns.

推荐答案

由于tb1中的单行在tb2中显然有很多行,因此您需要定义which行来挑选.或者是某种聚合?

此查询返回tb1中的所有符合条件的行,并添加tb2中最后创建的one匹配行中的列(如果有):

SELECT tb1.created_at, tb1.status, tb2.*
FROM   tb1
LEFT   JOIN LATERAL (
   SELECT tb2.source_id, tb2.destination_id
   FROM   tb2
   WHERE  tb2.tk_id = tb1.tk_id
   ORDER  BY created_at DESC, id DESC
   LIMIT  1
   ) tb2 ON true
WHERE  tb1.created_at > timezone('utc', now()) - interval '40 minutes';

Added id DESC as tiebreaker since created_at might not be unique.
Adapt to your undisclosed needs.

相关:

Support this query with an index on tb2(tk_id, created_at, id).
And another index on tb1(created_at), obviously. Or even a covering index on tb1(created_at) INCLUDE (tk_id, status). See:

Sql相关问答推荐

查询将查找将标记设置为user2的用户

解析键-值对,根据值 Select ,并使用SQL创建新列

如何查找所提供日期范围的所有季度开始日期和结束日期

SQL:如何在表中同时使用GROUPING和CONDITION?

将计算列设置为持久化的目的是什么?

在SQL Server中设置关联对象的有效JSON格式

了解多个分组集

PATINDEX中与[A-Z]匹配(U除外)的正则表达式

如何在连接中使用三个不同的列,从而在PostgreSQL中只获得两个列?

WooCommerce产品的SQL查询:获取sku和产品标签

如何在多列上编写具有不同条件的查询?

从JSON值数组创建扁平数组Athena

将SQL Server查询改进为;线程安全;

用替代方案替换 SQL Cursor 以提高性能

具有多个表 JOINS 的 STRING_AGG 的替代方法 (SQL Server 2016)

Postgres,使用 select 插入多个值

使用临时表判断记录是否存在 - 如果存在则执行相同的操作

如何通过子 Select 在一次更新(并行数组)中多次更新相同的行

如何在一个存储过程中创建全局临时表,并在另一个存储过程中使用它

SQL 中的问题与包含最大日期的记录连接