在 SQL 中:按相关元素时间戳对唯一元素进行排序

In SQL: order unique elements by related elements timestamp

我有两个表 "loans" 和 "payments"。贷款具有贷款状态,并且可能附有付款。付款具有贷款 ID、逾期状态和处理日期。

我想获得一份列表,其中包含 loan_status=1 的所有贷款,这些贷款至少有一笔现有逾期=真实付款,按匹配的付款处理日期排序。

下面是一些示例数据:

loan
+----+-------------+
| id | loan_status |
+----+-------------+
| 1  | 0           |
+----+-------------+
| 2  | 1           |
+----+-------------+
| 3  | 1           |
+----+-------------+
| 4  | 1           |
+----+-------------+
| 5  | 1           |
+----+-------------+

payment
+----+---------+----------------+---------------------+
| id | loan_id | overdue_status | processed_date      |
+----+---------+----------------+---------------------+
| 1  | 1       | f              | 2013-07-21 07:00:00 |
+----+---------+----------------+---------------------+
| 2  | 2       | f              | 2013-07-21 08:00:00 |
+----+---------+----------------+---------------------+
| 3  | 3       | f              | 2013-07-21 09:00:00 |
+----+---------+----------------+---------------------+
| 4  | 3       | t              | 2013-07-21 11:00:00 |
+----+---------+----------------+---------------------+
| 5  | 4       | f              | 2013-07-21 06:00:00 |
+----+---------+--------------------------------------+
| 6  | 4       | t              | 2013-07-21 10:00:00 |
+----+---------+----------------+---------------------+
| 7  | 4       | t              | 2013-07-21 13:00:00 |
+----+---------+----------------+---------------------+
| 8  | 5       | t              | 2013-07-21 10:30:00 |
+----+---------+----------------+---------------------+

通过下面的 sql 查询,我可以找到匹配的贷款,但未按处理日期排序:

select id from loan where loan_status = 1 and exists(
    select id from payment where
        payment.loan_id = loan.id and payment.overdue_status = 't')

我如何更改上面的 sql 查询(或创建一个新查询)以按最早的逾期付款 (processed_date) 排序贷款?

使用上述数据的预期结果应该是:

+----+-------------+
| id | loan_status |
+----+-------------+
| 4  | 1           | // 2013-07-21 10:00:00
+----+-------------+
| 5  | 1           | // 2013-07-21 10:30:00
+----+-------------+
| 3  | 1           | // 2013-07-21 11:00:00
+----+-------------+
SELECT a.id, loan_status from loan_status a 
inner join payment b on a.id = b.loan_id and b.overdue_status = 't' and loan_status = 1
GROUP BY a.id, loan_status, processed_date
ORDER BY processed_date

使用 inner join,这样您也可以从另一个 table 访问列。 (好吧,即使您不需要它,如果您使用内部联接,您的查询也会更好。无论如何,您所做的实际上是一个内部联接)

Select a.id, 
      loan_status,
      min(processed_date) as processed_date  
from loan as a 
inner join payment as b 
on a.id = b.loan_id 
and b.overdue_status = 't' and loan_status = 1
Group by a.id,loan_status
Order by processed_date

如果您只是寻找逾期付款,我认为您根本不需要 loan table

select p.*
from (select distinct on (p.loan_id) p.*
      from payment p
      where p.overdue_status = 't'
      order by p.loan_id, p.processed_date
     ) p
order by p.processed_date

如果您只想要状态 1 贷款:

select p.*
from (select distinct on (p.loan_id) p.*
      from payment p
      where p.overdue_status = 't' and
            p.loan_id in (select l.id from loan where l.status = 1)
      order by p.loan_id, p.processed_date
     ) p
order by p.processed_date;

您可以使用 group by 而不是 distinct on 作为逻辑。但是,distinct on 让我们引入第一个逾期付款所在行的所有属性。

试试下面的查询。上面回答的查询会出错,因为必须在 select

中指定按列名排序
SELECT Distinct x.id 
FROM 
(
    SELECT  a.id, loan_status, processed_date from loan_status a 
    INNER JOIN payment b on a.id = b.loan_id and b.overdue_status = 't' and loan_status = 1
    ORDER BY processed_date
) x