我有以下表格:
CREATE table table1 (id int , cd date, ct TIME, co text)
INSERT INTO table1
VALUES (0, '1/1/2018', '12:00:00', 'B'),
(1, '1/1/2018', '12:30:00', 'BC'),
(2, '1/12/2018', '12:00:00', 'B'),
(3, '1/22/2018', '12:00:00', 'BC')
当“cd”和“ct”列的值对于'B'和'BC'相同或者只有“ct”的值不同并且显示记录'B'的值时,我需要组合“co”列对于'B-BC'。 对于上面的表1记录,我需要以下结果:
"id" "cd" "ct" "co"
"0" "1/1/2018" "12:00:00 PM" "B-BC"
"2" "1/12/2018" "12:00:00 PM" "B"
"3" "1/22/2018" "12:00:00 PM" "BC"
在postgresql 8.4中最有效的方法是什么?
答案 0 :(得分:1)
我创建了两个公用表表达式(CTE)来提供将要组合的B和BC记录列表。逻辑是得到B记录和BC记录。然后执行从table1到cte_A表的左连接,并将join连接到cte_B表,但cte_b.id_del为null。这将删除cte_B中找到的id。最后,做一个何时对cte_A表中找到的id使用新的co值(B-BC)的情况。请参阅此处的演示:http://sqlfiddle.com/#!15/62caa/49
with cte_a as (select a.id as id_keep
from table1 a
inner join table1 b on a.cd=b.cd
and a.co='B' and b.co='BC')
,cte_b as (select b.id as id_del
from table1 a
inner join table1 b on a.cd=b.cd
and a.co='B' and b.co='BC')
select t1.id,
t1.cd,
t1.ct,
case when cte_a.id_keep is null
then t1.co
else 'B-BC' end as co
from table1 t1
left join cte_a
on t1.id=cte_a.id_keep
left join cte_b
on t1.id = cte_b.id_del
where cte_b.id_del is null;
答案 1 :(得分:0)
您可以使用string_agg
:
SELECT cd, MIN(id) AS id, min(ct) AS ct, string_agg(co, '-' ORDER BY ct) AS co
FROM table1
GROUP BY cd;
<强> DBFiddle Demo 强>
修改强>
可爱的答案!但是对于&#39; B&#39;并不总是最低价值。我需要ct,这是专门记录在&#39; B&#39;,它可能更大&#39;&#39;对于BC&#39;或更少
您可以使用窗口函数:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER(PARTITION BY cd ORDER BY ct ASC) AS rn FROM table1
)
SELECT id, cd, ct,s.co
FROM cte
JOIN LATERAL(SELECT string_agg(co, '-' ORDER BY ct) AS co
FROM cte c2 WHERE c2.cd=cte.cd)s ON TRUE
WHERE rn=1;
<强> DBFiddle Demo2 强>