Rob*_*ion 25 sql postgresql distinct elixir where
想象一下comments
,您的数据库中有一个表.
注释表有列,id
,text
,show
,comment_id_no
.
如果用户输入注释,它会在数据库中插入一行
| id | comment_id_no | text | show | inserted_at |
| -- | -------------- | ---- | ---- | ----------- |
| 1 | 1 | hi | true | 1/1/2000 |
Run Code Online (Sandbox Code Playgroud)
如果用户想要更新该注释,则会在数据库中插入新行
| id | comment_id_no | text | show | inserted_at |
| -- | -------------- | ---- | ---- | ----------- |
| 1 | 1 | hi | true | 1/1/2000 |
| 2 | 1 | hey | true | 1/1/2001 |
Run Code Online (Sandbox Code Playgroud)
注意它保持不变comment_id_no
.这样我们就可以看到评论的历史了.
现在用户决定他们不再想要显示他们的评论
| id | comment_id_no | text | show | inserted_at |
| -- | -------------- | ---- | ----- | ----------- |
| 1 | 1 | hi | true | 1/1/2000 |
| 2 | 1 | hey | true | 1/1/2001 |
| 3 | 1 | hey | false | 1/1/2002 |
Run Code Online (Sandbox Code Playgroud)
这隐藏了最终用户的评论.
现在发表第二条评论(不是第一条评论的更新)
| id | comment_id_no | text | show | inserted_at |
| -- | -------------- | ---- | ----- | ----------- |
| 1 | 1 | hi | true | 1/1/2000 |
| 2 | 1 | hey | true | 1/1/2001 |
| 3 | 1 | hey | false | 1/1/2002 |
| 4 | 2 | new | true | 1/1/2003 |
Run Code Online (Sandbox Code Playgroud)
我希望能够做的是选择所有最新版本的unique commend_id_no
,其中show
等于true.但是,我不希望返回查询id=2
.
查询需要采取的步骤......
comment_id_no
s.(应返回id=3
和id=4
)id=4
)注意:我实际上是使用ecto在elixir中编写此查询,并且希望能够在不使用子查询函数的情况下执行此操作.如果有人能在sql中回答这个问题,我可以自己转换答案.如果有人知道如何在灵药中回答这个问题,那么也随时回答.
Gar*_*thD 14
您可以在不使用子查询的情况下执行此操作LEFT JOIN
:
SELECT c.id, c.comment_id_no, c.text, c.show, c.inserted_at
FROM Comments AS c
LEFT JOIN Comments AS c2
ON c2.comment_id_no = c.comment_id_no
AND c2.inserted_at > c.inserted_at
WHERE c2.id IS NULL
AND c.show = 'true';
Run Code Online (Sandbox Code Playgroud)
我认为所有其他方法都需要某种子查询,这通常是通过排名函数完成的:
SELECT c.id, c.comment_id_no, c.text, c.show, c.inserted_at
FROM ( SELECT c.id,
c.comment_id_no,
c.text,
c.show,
c.inserted_at,
ROW_NUMBER() OVER(PARTITION BY c.comment_id_no
ORDER BY c.inserted_at DESC) AS RowNumber
FROM Comments AS c
) AS c
WHERE c.RowNumber = 1
AND c.show = 'true';
Run Code Online (Sandbox Code Playgroud)
由于您已使用Postgresql标记,您还可以使用DISTINCT ON ()
:
SELECT *
FROM ( SELECT DISTINCT ON (c.comment_id_no)
c.id, c.comment_id_no, c.text, c.show, c.inserted_at
FROM Comments AS c
ORDER By c.comment_id_no, inserted_at DESC
) x
WHERE show = 'true';
Run Code Online (Sandbox Code Playgroud)
我想你想要:
select c.*
from comments c
where c.inserted_at = (select max(c2.inserted_at)
from comments c2
where c2.comment_id_no = c.comment_id_no
) and
c.show = 'true';
Run Code Online (Sandbox Code Playgroud)
我不明白这有什么关系select distinct
。您只需要评论的最后一个版本,然后检查是否可以显示该版本。
编辑:
在 Postgres 中,我会这样做:
select c.*
from (select distinct on (comment_id_no) c.*
from comments c
order by c.comment_id_no, c.inserted_at desc
) c
where c.show
Run Code Online (Sandbox Code Playgroud)
distinct on
通常具有相当好的性能特征。