SQL 查询以根据 table 关系获取最后一条记录
SQL query to get last record based on table relation
我有 3 tables boxes, stones and papers;每个盒子都通过一块石头与一张纸相关,所以我的目标是为每张纸获取最后一个盒子(盒子可以共享纸张)。已尝试使用 ActiveRecord 方式进入 rails 但无法在 uuid 库中使用聚合函数,因此这不起作用:
Box.joins(:stone).group('stone.paper_id').maximum(:id).values
自从缺少石头 table 以来,我一直在努力寻求一个纯粹的 SQL 声明,我有以下内容:
select distinct on (papers.id) boxes.created_at, boxes.id
from papers
left join boxes on paper.id = boxes.id
order by paper.id, boxes.created_at DESC;
所有 3 个 table 主键都是 uuid 以及与查询无关的其他列,因为我只想 return 每篇论文的最后一个框的 uuid。
table:boxes
+--------------------------------------+-----------------+-----------+---------------------------------+--------------------------------------+
| id | email | delivered | created_at | stone_id |
+--------------------------------------+-----------------+-----------+---------------------------------+--------------------------------------+
| 61a341b0-a147-4534-9368-fdbc7b61fc0c | test@test.com | true | Fri, 04 Mar 2022 00:19:31 +0000 | 7fda6668-e9b2-45b3-957a-fbdbcd833cd0 |
| c20f4b61-8606-4aa7-870a-29b9df9d9492 | test2@test.com | true | Thu, 24 Feb 2022 11:42:01 +0000 | cdb35b8a-b553-4095-8b14-e855ebdf5044 |
| 9202384f-1895-4f94-9972-3ef837655aae | test3@test.com | false | Thu, 10 Mar 2022 00:59:54 +0000 | bbd5dcbc-b38d-4751-aaac-2b3dd83c5545 |
+--------------------------------------+-----------------+-----------+---------------------------------+--------------------------------------+
table:stones
+--------------------------------------+--------+------+---------------------------------+--------------------------------------+
| id | status | code | created_at | paper_id |
+--------------------------------------+--------+------+---------------------------------+--------------------------------------+
| 7fda6668-e9b2-45b3-957a-fbdbcd833cd0 | 1 | 3 | Sun, 06 Mar 2022 12:58:56 +0000 | a0acba15-e321-4f9f-996f-a6c16e56300d |
| cdb35b8a-b553-4095-8b14-e855ebdf5044 | 1 | 4 | Thu, 03 Mar 2022 19:57:14 +0000 | a0acba15-e321-4f9f-996f-a6c16e56300d |
| bbd5dcbc-b38d-4751-aaac-2b3dd83c5545 | 2 | 5 | Fri, 11 Mar 2022 11:50:08 +0000 | de936cf2-c158-4961-9ef4-60affc4ff87f |
+--------------------------------------+--------+------+---------------------------------+--------------------------------------+
table:papers
+--------------------------------------+------+---------------------------------+
| id | type | created_at |
+--------------------------------------+------+---------------------------------+
| a0acba15-e321-4f9f-996f-a6c16e56300d | 1 | Sat, 05 Mar 2022 05:59:00 +0000 |
| de936cf2-c158-4961-9ef4-60affc4ff87f | 5 | Thu, 03 Mar 2022 19:57:14 +0000 |
| 473a9dd4-3f38-49d0-8d1e-b5ab87e8ea92 | 4 | Sat, 12 Mar 2022 22:55:16 +0000 |
+--------------------------------------+------+---------------------------------+
box1 has a stone1 that relates to paper1
box2 has a stone2 that relates to paper1
box3 has a stone3 that relates to paper2
因此我想要 box1 和 box3 uuid,因为它们是最新的盒子(按创建时间排序)对于每篇可用的论文,box2 被忽略,因为 paper1 与 box1 共享,而且它不是最新的。任何帮助都感激不尽!提前致谢!
result:most recent boxes ids
+--------------------------------------+
| id |
+--------------------------------------+
| 61a341b0-a147-4534-9368-fdbc7b61fc0c |
| 9202384f-1895-4f94-9972-3ef837655aae |
+--------------------------------------+
试试这个:
SELECT DISTINCT ON (p.id)
b.id
FROM boxes AS b
INNER JOIN stones AS s
ON s.id = b.stone_id
INNER JOIN papers AS p
ON p.id = s.paper_id
ORDER BY p.id, b.created_at DESC
查看dbfiddle中的测试结果。
"SQL 根据 table 关系查询获取最后一条记录"
table 中没有记录,只是按任意顺序分组到页中的逻辑行。在 table 页面中没有像电子表格那样的默认或特定顺序,并且行作为堆放置在页面中。您一定很清楚,您将永远无法找到最后的“记录”!
在数据库中,您会发现,只有您要存储的内容。如果 you 想要找到 you 插入的最后一行,you 需要在插入语句。
我说 YOU,因为任何其他用户都可以同时使用相同的值执行相同的插入...这就是并发!
现在的问题是“你想要什么功能?”
您可以执行此查询 (Result here)
with x as (
select row_number() over (partition by p.id order by b.created_at desc) as rn,b.id as id_box,p.id as id_paper
from boxes b join stones s on b.stone_id = s.id
join papers p on p.id = s.paper_id)
select x.id_box from x where rn = 1
cte
根据与 papers
table 相关的 paper_id
找到最新的 id
。然后加入 box
table.
尝试告诉我是否有帮助:
with cte as
(
select s.id,
s.paper_id,row_number() over(partition by paper_id order by created_at desc ) as rn
from stones s
) select b.id
from boxes b
inner join cte c on c.id=b.stone_id
inner join papers p on c.paper_id=p.id
where c.rn=1
order by b.created_at desc;
Result:
id
9202384f-1895-4f94-9972-3ef837655aae
61a341b0-a147-4534-9368-fdbc7b61fc0c
我有 3 tables boxes, stones and papers;每个盒子都通过一块石头与一张纸相关,所以我的目标是为每张纸获取最后一个盒子(盒子可以共享纸张)。已尝试使用 ActiveRecord 方式进入 rails 但无法在 uuid 库中使用聚合函数,因此这不起作用:
Box.joins(:stone).group('stone.paper_id').maximum(:id).values
自从缺少石头 table 以来,我一直在努力寻求一个纯粹的 SQL 声明,我有以下内容:
select distinct on (papers.id) boxes.created_at, boxes.id
from papers
left join boxes on paper.id = boxes.id
order by paper.id, boxes.created_at DESC;
所有 3 个 table 主键都是 uuid 以及与查询无关的其他列,因为我只想 return 每篇论文的最后一个框的 uuid。
table:boxes
+--------------------------------------+-----------------+-----------+---------------------------------+--------------------------------------+
| id | email | delivered | created_at | stone_id |
+--------------------------------------+-----------------+-----------+---------------------------------+--------------------------------------+
| 61a341b0-a147-4534-9368-fdbc7b61fc0c | test@test.com | true | Fri, 04 Mar 2022 00:19:31 +0000 | 7fda6668-e9b2-45b3-957a-fbdbcd833cd0 |
| c20f4b61-8606-4aa7-870a-29b9df9d9492 | test2@test.com | true | Thu, 24 Feb 2022 11:42:01 +0000 | cdb35b8a-b553-4095-8b14-e855ebdf5044 |
| 9202384f-1895-4f94-9972-3ef837655aae | test3@test.com | false | Thu, 10 Mar 2022 00:59:54 +0000 | bbd5dcbc-b38d-4751-aaac-2b3dd83c5545 |
+--------------------------------------+-----------------+-----------+---------------------------------+--------------------------------------+
table:stones
+--------------------------------------+--------+------+---------------------------------+--------------------------------------+
| id | status | code | created_at | paper_id |
+--------------------------------------+--------+------+---------------------------------+--------------------------------------+
| 7fda6668-e9b2-45b3-957a-fbdbcd833cd0 | 1 | 3 | Sun, 06 Mar 2022 12:58:56 +0000 | a0acba15-e321-4f9f-996f-a6c16e56300d |
| cdb35b8a-b553-4095-8b14-e855ebdf5044 | 1 | 4 | Thu, 03 Mar 2022 19:57:14 +0000 | a0acba15-e321-4f9f-996f-a6c16e56300d |
| bbd5dcbc-b38d-4751-aaac-2b3dd83c5545 | 2 | 5 | Fri, 11 Mar 2022 11:50:08 +0000 | de936cf2-c158-4961-9ef4-60affc4ff87f |
+--------------------------------------+--------+------+---------------------------------+--------------------------------------+
table:papers
+--------------------------------------+------+---------------------------------+
| id | type | created_at |
+--------------------------------------+------+---------------------------------+
| a0acba15-e321-4f9f-996f-a6c16e56300d | 1 | Sat, 05 Mar 2022 05:59:00 +0000 |
| de936cf2-c158-4961-9ef4-60affc4ff87f | 5 | Thu, 03 Mar 2022 19:57:14 +0000 |
| 473a9dd4-3f38-49d0-8d1e-b5ab87e8ea92 | 4 | Sat, 12 Mar 2022 22:55:16 +0000 |
+--------------------------------------+------+---------------------------------+
box1 has a stone1 that relates to paper1
box2 has a stone2 that relates to paper1
box3 has a stone3 that relates to paper2
因此我想要 box1 和 box3 uuid,因为它们是最新的盒子(按创建时间排序)对于每篇可用的论文,box2 被忽略,因为 paper1 与 box1 共享,而且它不是最新的。任何帮助都感激不尽!提前致谢!
result:most recent boxes ids
+--------------------------------------+
| id |
+--------------------------------------+
| 61a341b0-a147-4534-9368-fdbc7b61fc0c |
| 9202384f-1895-4f94-9972-3ef837655aae |
+--------------------------------------+
试试这个:
SELECT DISTINCT ON (p.id)
b.id
FROM boxes AS b
INNER JOIN stones AS s
ON s.id = b.stone_id
INNER JOIN papers AS p
ON p.id = s.paper_id
ORDER BY p.id, b.created_at DESC
查看dbfiddle中的测试结果。
"SQL 根据 table 关系查询获取最后一条记录"
table 中没有记录,只是按任意顺序分组到页中的逻辑行。在 table 页面中没有像电子表格那样的默认或特定顺序,并且行作为堆放置在页面中。您一定很清楚,您将永远无法找到最后的“记录”!
在数据库中,您会发现,只有您要存储的内容。如果 you 想要找到 you 插入的最后一行,you 需要在插入语句。
我说 YOU,因为任何其他用户都可以同时使用相同的值执行相同的插入...这就是并发!
现在的问题是“你想要什么功能?”
您可以执行此查询 (Result here)
with x as (
select row_number() over (partition by p.id order by b.created_at desc) as rn,b.id as id_box,p.id as id_paper
from boxes b join stones s on b.stone_id = s.id
join papers p on p.id = s.paper_id)
select x.id_box from x where rn = 1
cte
根据与 papers
table 相关的 paper_id
找到最新的 id
。然后加入 box
table.
尝试告诉我是否有帮助:
with cte as
(
select s.id,
s.paper_id,row_number() over(partition by paper_id order by created_at desc ) as rn
from stones s
) select b.id
from boxes b
inner join cte c on c.id=b.stone_id
inner join papers p on c.paper_id=p.id
where c.rn=1
order by b.created_at desc;
Result:
id 9202384f-1895-4f94-9972-3ef837655aae 61a341b0-a147-4534-9368-fdbc7b61fc0c