我具有以下架构和数据:
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
这有效。我在这里摆弄着:https://www.db-fiddle.com/f/qMmJ6UxMfx8Fd87wgAsaBs/0
但是我想做的是
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的情况下,在some_val中查找值为缩略图或首次失败的值,并将记录归为结果。
我知道这是开放式的。我什至不知道从哪里开始。这是我需要数据透视表的地方吗?我对这些内容了解不多,但是在查询过程中会创建一个临时表。还是我需要子查询?我在其中选择(查询缩略图记录)AS缩略图,(查询first_failure AS首次失败)。否则会容易得多,而且我会使事情变得过于复杂。
任何标题的改进都将受到欢迎。
答案 0 :(得分:0)
您似乎正在寻找条件聚合:
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 | thumbnail | first_failure |
| --- | --------- | ------------- |
| 1 | 53 | 42 |
| 2 | 54 | |
要根据给定的芯片ID进行过滤,您只需添加一个where
子句(它位于group by
子句之前)。
答案 1 :(得分:0)
以下内容接近。它返回:
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;
Here是db <>小提琴。
很容易将chip_id
放入字符串中。我只是不确定那是否是您真正想要的-为什么您不进行一项测量却包含ID?
而且,我想到您可能真的想要JSON。
答案 2 :(得分:0)
我想您将要使用json表示该结果行。您可以使用json functions,特别是aggregate function json_object_agg
来构造它:
SELECT chip_id, json_object_agg(some_val, record)
FROM test_records
GROUP BY chip_id
1 { "thumbnail" : 53, "first_failure" : 42, "another_metric" : 33 }
2 { "thumbnail" : 54 }
现在可以在该对象中获得芯片ID甚至更好的名称,我可以想到两种方法。第一个将使用jsonb_set
在聚合对象中创建一个新键:
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
子句来过滤单个结果,而不是使用上面演示的GROUP BY id
。您甚至可以对chip_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