【问题标题】:string substitution with query result postgresql用查询结果替换字符串 postgresql
【发布时间】:2012-09-28 10:31:26
【问题描述】:

我有一个查询,结果总是只返回一个元素。我想将此查询的结果附加到一个字符串中,以便进一步处理

例子

select id from ids where some_condition

我想把这个 id 附加到一个字符串中

类似于result_(id)_table,其中,id 必须替换为从前一个查询返回的 id(本质上是另一个表)

最后,我应该能够执行类似的查询

select * from result_id_table

其中,“result_id_table”是 id 被适当替换的表的名称

【问题讨论】:

  • 我不太明白这个问题。您希望 ids 中的每个 id 在表中进行查询,该表的名称是通过替换 id 来创建的?或类似的东西?如果它是远程这样的,我觉得你需要dynamic sql 和/或可能是临时表。

标签: postgresql psql


【解决方案1】:

使用字符串连接:

-- Demo table structure
CREATE TABLE dummy ( id integer primary key, blah integer not null);
INSERT INTO dummy(id, blah) VALUES (1,1);

-- Single-valued query
SELECT id FROM dummy WHERE blah = 1;

-- Formatted with string concatenation
SELECT 'result_'||(id::text)||'_table' FROM dummy WHERE blah = 1;

-- Formatted using the `format` function
SELECT format('result_%s_table', id) FROM dummy WHERE blah = 1;

如果您正在收集其他信息,请使用子查询组合成字符串

SELECT 'result_'||(SELECT id FROM dummy WHERE blah = 1)||'_table'
FROM .... WHERE ...

或使用连接。

您的编辑表明您希望将其用作表名。这可能意味着您的设计很糟糕。而不是:

CREATE TABLE sometable_1 ( id integer primary key, ...);
CREATE TABLE sometable_2 ( id integer primary key, ...);
CREATE TABLE sometable_3 ( id integer primary key, ...);
...
CREATE TABLE sometable_n ( id integer primary key, ...);

你几乎总是更好:

CREATE TABLE sometable(
     id integer not null,
     discriminator integer not null,
     primary key (id, discriminator),
     ...
);

或每个模式表。如果由于某种原因您坚持使用这种方法,您可以使用 PL/PgSQL 的 EXECUTE 语句来运行动态 SQL,例如:

EXECUTE format('SELECT * FROM sometable_%s WHERE blah = ?', 
            quote_ident((SELECT id FROM dummy WHERE blah = 1))
        )
USING 2;

查询“sometable_1”中“blah = 2”的行。手册中的更多信息,请参阅EXECUTE ... USING

在 PostgreSQL 的常规 SQL 中根本不可能做到这一点。在应用程序或 PL/PgSQL 中执行此操作。可以使用 PL/PgSQL DO 块,但如果您在所有事情上都依赖它,性能将会糟糕

立即修复您的设计,以免为时已晚。

【讨论】:

  • 您好,如何使用查询结果,即result_id_table(其中id使用格式或字符串concat替换)作为表名?
  • @pravinkenator 啊,你想要动态 SQL。这通常表明存在严重的设计问题,您应该在目标表中使用附加列,但偶尔也可以。如果必须这样做,唯一的方法是使用 PL/PgSQL 的 EXECUTE 语句。
  • @pravinkenator 更新了解释。下次尝试更好地解释您的问题,实际上甚至不清楚您真正想要什么。
  • 谢谢!我得到了它。精彩的帖子!
  • @pravinkenator 很高兴为您提供帮助。如果您愿意,请随时 +1 :-) 并感谢您的接受。听起来您可能正在尝试多租户数据库设计,因此请尝试搜索“postgresql 多租户”以了解如何使用模式和search_path 或使用复合主键更轻松/安全地完成它。
【解决方案2】:

我在 Redshift 上使用 Postgres,遇到了尝试在 etl 中使用动态日期的问题并找到了解决方案。

使用变量值的一种正确方法是使用f' '

query = f''' select * from table where date >= '{my_date}' order by date '''

免责声明:这不是一个安全的解决方案,但您可以将其更改为使用 sqlalchemy textbindparam--- Docs on sqlalchemy

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-14
    • 2012-10-18
    相关资源
    最近更新 更多