Postgresql 如何在postgres中将查询结果解析为字符串?
我准备了sql小提琴: 模式如下:Postgresql 如何在postgres中将查询结果解析为字符串?,postgresql,Postgresql,我准备了sql小提琴: 模式如下: CREATE TABLE products ("id" int, "name" varchar(5)) ; INSERT INTO products ("id", "name") VALUES (1, 'Car'), (2, 'Phone') ; CREATE TABLE operations ("id" int, "product_id" int, "status" varchar(7), "type" varch
CREATE TABLE products
("id" int, "name" varchar(5))
;
INSERT INTO products
("id", "name")
VALUES
(1, 'Car'),
(2, 'Phone')
;
CREATE TABLE operations
("id" int, "product_id" int, "status" varchar(7), "type" varchar(8))
;
INSERT INTO operations
("id", "product_id", "status", "type")
VALUES
(1, 1, 'pending', 'invoice'),
(2, 1, 'done', 'delivery'),
(3, 2, 'done', 'delivery'),
(3, 2, 'done', 'invoice')
;
我知道数据模式可能会更好,但我现在不可能重构它——我只是在添加新视图。
关于模式的说明:产品始终有两个操作:开票和交付。
我想要达到的是这样的结果:
name status
car pending
phone done
其中product status是检查两个产品操作后返回的字符串。规则是,只有当两个操作都完成时,产品状态才完成,否则它将挂起。
如何在postgres中编写这样的查询?
select
select
p.name,
case
when count(case when status <> 'done' then 1 else null end) = 0 then 'done'
else 'pending'
end status
from products p
inner join operations o on p.id = o.product_id
group by p.name, p.id;
p、 名字,
案例
当计数(状态为“完成”时为1,否则为空结束)=0,然后为“完成”
其他“待定”
结束状态
来自产品p
p.id=o.product\u id上的内部联接操作o
按p.name、p.id分组;
您可以创建两个子查询,一个用于订单,另一个用于交货,将它们连接起来,然后使用case
表达式检查这两个子查询的状态:
SELECT invoice.name,
CASE WHEN invoice.status = 'done' and delivery.status = 'done' THEN 'done'
ELSE 'pending'
END AS status
FROM (SELECT p.name, p.id, o.status
FROM products p
JOIN operations o ON o.type = 'invoice' AND
o.product_id = p.id) invoice
JOIN (SELECT p.name, p.id, o.status
FROM products p
JOIN operations o ON o.type = 'delivery' AND
o.product_id = p.id) delivery
ON invoice.id = delivery.id
首先,我们将不同的值串联在一个字符串中(string\u agg
),然后在主查询中检查:如果ne字符串是单个的'done'
,这意味着所有操作都'done'
。否则,一个或两个操作都是“挂起的”
由于您的外键是
products.id operations.product\u id
我们必须按分组products.id
您可以将SQLFIDLE中的SQL语句添加到您的问题中吗。SQLFiddle当前不起作用(对我来说)@a_horse_,没有完成名称,感谢您的评论如果产品名称不唯一,则此分组是错误的。查询应该更通用,因为我们对名称唯一性一无所知,是的,我同意。固定的。
SELECT p.name, CASE WHEN status='done' THEN 'done' else 'pending' END
FROM (
SELECT p.id, p.name, string_agg(distinct o.status, '') as status
FROM products p JOIN operations o ON o.product_id = p.id
GROUP BY p.id, p.name
) sub