如何在postgres中将查询结果解析为字符串?

时间:2015-10-30 09:36:05

标签: postgresql

我准备了sql小提琴:http://sqlfiddle.com/#!15/62e65/2

架构就在这里:

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')
;

我知道数据架构可能更好,但我现在没有可能重构它 - 我只是添加新视图。 关于架构的注意事项:产品总是有2个操作:开票和交货。 我想要达到的目的是获得这样的结果:

name status
car pending
phone done

产品状态是检查两个产品操作后返回的字符串 规则是产品状态仅在两个操作完成时完成,否则其待定 如何在postgres中编写这样的查询?

3 个答案:

答案 0 :(得分:1)

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

我们在一个字符串(string_agg)中连接不同的值,然后在主查询中检查:如果ne string是单'done',那么所有操作都是'done'。否则,一个或两个操作都是'pending'

由于您的外键是products.id <--> operations.product_id,我们必须GROUP BY products.id

答案 1 :(得分:0)

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;

答案 2 :(得分:0)

您可以创建两个子查询,一个用于订单,一个用于交付,加入它们,然后使用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