Sql 查询返回与逗号分隔字符串具有相同 ID 的元素
我有两个表,table1
有entry_ID
、entry_date
和其他条目信息。 table2
具有 entry_ID
和 entry_subject
。每个entry_ID
可以有任意多个entry_subjects
。
我想要一个查询,该查询将返回 entry_ID
、entry_date
以及与该条目对应的主题列表,以逗号分隔。
第一步似乎只是获取一个返回 entry_ID
和来自 table2
的以逗号分隔的主题列表的查询。一旦我知道加入应该很容易。
我改编了此站点的递归 CTE 方法:以适合我的情况:
WITH RECURSIVE CTE (entry_ID, subjectlist, subject, length)
AS ( SELECT entry_ID, cast( '' as varchar(8000))
, cast( '' as varchar(8000)), 0
FROM table2
GROUP BY entry_ID
UNION ALL
SELECT t2.entry_ID,
cast(subjectlist || CASE length = 0 THEN '' ELSE ', ' END
|| entry_subject AS varchar(8000) ),
cast (t2.entry_subject as varchar(8000)),
length +1
FROM CTE c
INNER JOIN table2 t2
on c.entry_ID=t2.entry_ID where t2.entry_subject > c.subject)
SELECT entry_ID, subjectlist FROM (
SELECT entry_ID, subjectlist, RANK() OVER (
PARTITION BY entry_ID order by length DESC)
FROM CTE) D (entry_ID, subjectlist, rank) where rank = 1;
并且它有效,我得到了我所期望的回应。为了实现我的最终目标,我使用的查询是这样的:
SELECT t1.* t2.subjectlist FROM table1
JOIN (ABOVE QUERY) AS t2 on t1.entry_ID=t2.entry_ID;
这看起来非常笨拙。这真的是最好的方法吗?
I have two tables, table1
has a entry_ID
, entry_date
and other entry information. table2
has entry_ID
and entry_subject
. Each entry_ID
can have arbitrarily many entry_subjects
.
I want a query that will return an entry_ID
, entry_date
, and a list of the subjects corresponding to that entry separated by commas.
The first step in this seems to be just getting a query that returns an entry_ID
and a comma separated list of subjects from table2
. Once I have that the join should be easy.
I adapted the recursive CTE method from this site: to fit my case:
WITH RECURSIVE CTE (entry_ID, subjectlist, subject, length)
AS ( SELECT entry_ID, cast( '' as varchar(8000))
, cast( '' as varchar(8000)), 0
FROM table2
GROUP BY entry_ID
UNION ALL
SELECT t2.entry_ID,
cast(subjectlist || CASE length = 0 THEN '' ELSE ', ' END
|| entry_subject AS varchar(8000) ),
cast (t2.entry_subject as varchar(8000)),
length +1
FROM CTE c
INNER JOIN table2 t2
on c.entry_ID=t2.entry_ID where t2.entry_subject > c.subject)
SELECT entry_ID, subjectlist FROM (
SELECT entry_ID, subjectlist, RANK() OVER (
PARTITION BY entry_ID order by length DESC)
FROM CTE) D (entry_ID, subjectlist, rank) where rank = 1;
And it works, I get the response I expect. To achieve my final goal the query I use is this:
SELECT t1.* t2.subjectlist FROM table1
JOIN (ABOVE QUERY) AS t2 on t1.entry_ID=t2.entry_ID;
This seems very unwieldy. Is this really the best way to do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果我理解正确,那么应该有一个更简单的解决方案。
测试设置
根据您的描述 - 您可以为我们这样做:
回答
string_agg()
需要 Postgres 9.0+或者,如果您想要对 Entry_subjects 排序:
您可以执行以下操作与在
table2
上对第一个ORDER BY entry_subject
进行子选择相同。If I understand correctly, then there should be a much simpler solution.
Test setup
According to your description - you could have done that for us:
Answer
string_agg()
requires Postgres 9.0+Or, if you want the entry_subjects sorted:
You could do the same with a subselect on
table2
to firstORDER BY entry_subject
.