返回SQL中每个行的映射值和传递值

时间:2014-01-28 22:30:34

标签: sql postgresql cartesian-product

我有一组元组

(id1, count1),(id2, count2) ... (idN, countN)

我在PostgreSQL数据库中有表

| tuple_id | project_id |

元组由外部应用程序生成并作为数据流传递。

我现在需要做的是将元组的 id 映射到数据库中的 project_id ,这样就会生成

(projectid1, count1), (projectid2, count2) ... (projectidM, countM)

其中 M< = N - 并非每个输入元组都在表中有适当的映射。

如果我只需要获取ID映射 ​​- 那么我会做类似

的事情
SELECT project_id FROM tablename WHERE tuple_id IN ( ..... )

但是我需要 project_id和count值。有没有其他方法可以在不创建临时表的情况下实现这一点,然后用流中的数据填充它?

示例输入数据(文本文件)

1,10
2,15
3,14

数据映射(PostgreSQL表)

1, 37f6e23f-ef50-4c6f-a746-cb29ae3adf52
2, 8c73500f-2118-4bb7-b470-78ac1878896e
3, c28b19f2-9ec7-4278-ae02-1dbb39d6113d

预期结果:

37f6e23f-ef50-4c6f-a746-cb29ae3adf52, 10
8c73500f-2118-4bb7-b470-78ac1878896e, 15
c28b19f2-9ec7-4278-ae02-1dbb39d6113d, 14

2 个答案:

答案 0 :(得分:2)

您可以使用外部数据包装器(FDW)来读取文件,就好像它是一个数据库表一样,然后将它连接到您的ID映射表。

file fdw看起来适合此任务。

这似乎有效:

CREATE TABLE mappings(id INT PRIMARY KEY, project_id UUID);
INSERT INTO mappings(id,project_id) VALUES 
    (1, '37f6e23f-ef50-4c6f-a746-cb29ae3adf52'),
    (2, '8c73500f-2118-4bb7-b470-78ac1878896e'),
    (3, 'c28b19f2-9ec7-4278-ae02-1dbb39d6113d');

CREATE EXTENSION file_fdw;
CREATE SERVER filedata FOREIGN DATA WRAPPER file_fdw;
CREATE FOREIGN TABLE textfile (tupleid int, id_count int) 
    SERVER filedata OPTIONS ( filename '/tmp/test1.txt', format 'csv' );

SELECT project_id, id_count 
    FROM textfile 
    LEFT join mappings on textfile.tupleid=mappings.id;

              project_id              | id_count
--------------------------------------+----------
 37f6e23f-ef50-4c6f-a746-cb29ae3adf52 |       10
 8c73500f-2118-4bb7-b470-78ac1878896e |       15
 c28b19f2-9ec7-4278-ae02-1dbb39d6113d |       14
(3 rows)

file-fdw对文件格式似乎有点挑剔。我发现最后一个空行导致它失败。

答案 1 :(得分:0)

嗯,我知道这很愚蠢,但它回答了这个问题:在单个查询中检索了所有必需的信息,没有创建临时表:

select project_id, 
    (CASE tuple_id WHEN 1 THEN 10 WHEN 2 THEN 15 WHEN 3 THEN 14 END) as count
from tablename where tuple_id in (1,2,3)

您只需要生成简单的CASE语句。

我相信用很多tuple_ids调用可能会很慢,但你没有说出限制/尺寸。