Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
返回与逗号分隔字符串ID相同的元素的Sql查询_Sql_Postgresql_Aggregate Functions - Fatal编程技术网

返回与逗号分隔字符串ID相同的元素的Sql查询

返回与逗号分隔字符串ID相同的元素的Sql查询,sql,postgresql,aggregate-functions,Sql,Postgresql,Aggregate Functions,我有两个表,table1有一个entry\u ID,entry\u date和其他条目信息表2有条目ID和条目主题。每个entry\u ID可以有任意多个entry\u主题 我需要一个查询,该查询将返回条目ID,条目日期,以及与该条目对应的主题列表(用逗号分隔) 这其中的第一步似乎只是获取一个查询,该查询返回条目ID和表2中以逗号分隔的主题列表。一旦我知道了,加入应该很容易。 我修改了:以适合我的情况: WITH RECURSIVE CTE (entry_ID, subjectlist, sub

我有两个表,
table1
有一个
entry\u ID
entry\u date
和其他条目信息<代码>表2有
条目ID
条目主题
。每个
entry\u ID
可以有任意多个
entry\u主题

我需要一个查询,该查询将返回
条目ID
条目日期
,以及与该条目对应的主题列表(用逗号分隔)

这其中的第一步似乎只是获取一个查询,该查询返回
条目ID
表2
中以逗号分隔的主题列表。一旦我知道了,加入应该很容易。
我修改了:以适合我的情况:

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; 

这似乎很笨拙。这真的是最好的方法吗?

如果我理解正确,那么应该有一个更简单的解决方案

测试设置 根据您的描述-您可以为我们这样做:

CREATE TABLE table1 (
   entry_id int4 PRIMARY KEY
 , entry_date date
);

CREATE TABLE table2 (
   entry_id int4 REFERENCES table1 (entry_id)
 , entry_subject text
 , PRIMARY KEY (entry_id, entry_subject)
);

INSERT INTO table1 VALUES (1, '2011-09-01'), (2, '2011-09-02'),(3, '2011-09-03');
INSERT INTO table2 VALUES (1, 'foo1'), (2, 'foo2'), (2, 'bar2')
                        , (3, 'foo3'), (3, 'baz3'), (3, 'bar3');  
答复
string\u agg()
需要Postgres 9.0+

SELECT t1.entry_id, t1.entry_date
     , string_agg(t2.entry_subject, ', ') AS entry_subjects
FROM   table1 t1
JOIN   table2 t2 USING (entry_id)
GROUP  BY 1,2
ORDER  BY 1;

 entry_id | entry_date | entry_subjects
----------+------------+------------------
        1 | 2011-09-01 | foo1
        2 | 2011-09-02 | bar2, foo2
        3 | 2011-09-03 | baz3, bar3, foo3
或者,如果要对条目进行排序,请执行以下操作:

SELECT DISTINCT ON (1)
       t1.entry_id
     , t1.entry_date
     , string_agg(t2.entry_subject, ', ') OVER (
          PARTITION BY t1.entry_id ORDER BY t2.entry_subject
          RANGE BETWEEN UNBOUNDED PRECEDING
                    AND UNBOUNDED FOLLOWING) AS entry_subjects
  FROM table1 t1
  JOIN table2 t2 USING (entry_id)
  ORDER BY 1;

 entry_id | entry_date | entry_subjects
----------+------------+------------------
        1 | 2011-09-01 | foo1
        2 | 2011-09-02 | bar2, foo2
        3 | 2011-09-03 | bar3, baz3, foo3

您也可以在
表2
上进行子选择,以首先
按条目排序\u subject

个人而言,如果可能的话,我会在数据库之外的中间层进行此操作。您所说的中间层是什么意思?我想我可以在一个进行数据库调用的bash脚本中更容易地实现这一点,但我使用的是一个实用程序库,它接受输入字符串,并将其解释为查询,然后直接在相应的数据库中执行。哦,我没有得到这种区别。是的,这就是我的意思。string_agg函数只在postgres 9.0中引入,我有一个早期版本。然而,这让我想到了使用array_to_string和array_agg的组合来做与string_agg相同的事情。非常感谢你的帮助!是的,string_agg()只是array_到_string(array_agg(..)的一个(非常方便的)快捷方式)