Sql 如何将多行滚动到一个摘要行中?

Sql 如何将多行滚动到一个摘要行中?,sql,postgresql,Sql,Postgresql,我有以下模式和数据: create table chips ( ID serial PRIMARY KEY, name VARCHAR (255) NOT NULL ); create table test_records ( chip_id INTEGER, some_val VARCHAR (255), record INTEGER ); insert into chips values (1,'chip_1'), (2,'chip_2'); insert

我有以下模式和数据:

create table chips (
  ID serial PRIMARY KEY,
  name VARCHAR (255) NOT NULL
  );

create table test_records (
  chip_id INTEGER,
  some_val VARCHAR (255),
  record INTEGER
  );

insert into chips values 
(1,'chip_1'),
(2,'chip_2');
insert into test_records values
(1,'thumbnail',53),
(1,'first_failure',42),
(1,'another_metric',33),
(2,'thumbnail',54)
然后,我尝试运行以下sql:

select * 
FROM 
chips 
INNER JOIN test_records ON test_records.chip_id = chips.id
WHERE 
chips.id = 1
这很有效。我这里有一把小提琴:

但我想做的是

select
chip.id
test_record.thumbnail
test_record.first_failure
FROM 
test_records
INNER JOIN chips ON chips.id = test_record.chips
WHERE 
chips.id = 1
有一行看起来像

(chip_id:1, thumbnail:53,first_failure:42)
这当然不行,因为缩略图和first_failure不是列。 我基本上希望它,当chip_id为1时,通过这些连接,在值为缩略图或首次失败的某个值中查找值,并将记录属性化为结果中的值

我知道这是一种开放式的。我甚至不知道从哪里开始。这是我需要透视表的地方吗?我对这些不太了解,但它会在查询期间创建一个临时表。或者我需要一个子查询?其中,我选择查询缩略图记录作为缩略图,查询第一次失败作为第一次失败。还是更简单,我把事情搞得太复杂了


此外,任何标题的改进都是受欢迎的

您似乎在寻找条件聚合:

select
    c.id,
    max(case when r.some_val  = 'thumbnail' then r.record end) thumbnail,
    max(case when r.some_val  = 'first_failure' then r.record end) first_failure
from 
    chips c
    inner join test_records r on c.id = r.chip_id
group by c.id
:


要对给定的芯片id进行过滤,只需在group by子句之前添加where子句即可。

以下内容即将完成。它返回:

id    value
1     (thumbnail:53, first_failure:42, another_metric:33)
查询是:

select c.id, '(' || string_agg(some_val || ':' || record, ', ') || ')' as value
FROM chips c INNER JOIN
     test_records tr
     ON tr.chip_id = c.id
WHERE c.id = 1
GROUP BY c.id;
他是一把小提琴

很容易将芯片id放入字符串中。我只是不确定这是否是你真正想要的——为什么你要省略一个测量值,而包括id


我突然想到,您可能真的需要JSON。

我认为您需要使用JSON来表示结果行。您可以使用构造它,特别是:

现在,为了得到芯片id,或者更好的名称,在这个对象中,我可以想到两种方法。第一个将使用jsonb_集在聚合对象中创建一个新键:

select jsonb_set(jsonb_object_agg(some_val, record), '{chip_name}'::text[], to_jsonb(name))
FROM chips 
INNER JOIN test_records ON test_records.chip_id = chips.id
GROUP BY id
第二种方法是从联合中选择聚合:

SELECT json_object_agg(key, value)
FROM (TABLE test_records
  UNION ALL
  SELECT id, 'chip_id', id
  FROM chips) as kv(id, key, value)
GROUP BY id

当然,您也可以使用WHERE子句来筛选单个结果,而不是使用上面演示的GROUPBY id。您甚至可以对chip_id键的值进行硬编码:

1   { "thumbnail" : 53, "first_failure" : 42, "another_metric" : 33 }
2   { "thumbnail" : 54 }
select jsonb_set(jsonb_object_agg(some_val, record), '{chip_name}'::text[], to_jsonb(name))
FROM chips 
INNER JOIN test_records ON test_records.chip_id = chips.id
GROUP BY id
SELECT json_object_agg(key, value)
FROM (TABLE test_records
  UNION ALL
  SELECT id, 'chip_id', id
  FROM chips) as kv(id, key, value)
GROUP BY id
SELECT json_object_agg(key, value)
FROM (SELECT some_val as key, record as value
  FROM test_records
  WHERE chip_id = 1
  UNION ALL
  VALUES ('chip_id', 1)
) kv