在 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
我有两个表 "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