假设我在两个不同的数据库中有一个名为
static
的表
and
。
静态
表包含房屋的静态信息,如house_size
、no_rooms
、池
、spa
。
< code>houses
数据库中的< code>static表具有如下列:
pool spa house_size sauna no_rooms
1 1 25 1 2
1 0 35 1 3
< code>apartments数据库中的< code>static表具有如下列:
pool spa house_size sauna
1 1 25 1
1 0 35 1
我想在不引发任何错误的情况下运行下面的查询。目前,我得到错误,因为no_rooms
列不存在于apartments.public.static
中。
select pool, case when spa = 1 then 1 else 0 end as has_spa,
sauna, house_size, case when no_rooms > 2 then 1 else 0 end as rooms
from static;
我尝试的解决方案:
WITH static_new AS (SELECT s.*
FROM (SELECT 0 AS no_rooms) AS dummy
LEFT JOIN LATERAL
( SELECT
pool, spa, sauna, house_size, no_rooms
FROM static
) AS s on true)
SELECT * FROM static_new;
它有效,但是当涉及更多列时,此查询会变得混乱。
我在寻找什么:
> < li>
创建一个函数,该函数采用列名和表名,然后执行我在上述查询中执行的联接,并返回一个表。(应该是通用的,适用于参数中给定的列名和表名,并返回一个表。)
还有其他漂亮整洁的解决方案吗?
不要纠结于查询。向包含所有列的两个数据库添加一个视图。在第一个数据库中:
create view v_static as
select pool, spa house_size, sauna, no_rooms
from status;
在第二个:
create view v_static as
select pool, spa house_size, sauna, null as no_rooms
from status;
然后使用视图而不是基表。
SQL是一种严格类型化的语言,Postgres函数必须声明它们的返回类型。从函数中返回可变数量的列只有通过变通方法才有可能,比如多态类型。参见:
但是在您的情况下,我们不能使用行类型,因为这因数据库而异。剩下的选择是:返回匿名记录,并为每次调用提供列定义列表。我通常不建议这样做,因为每次调用都提供列定义列表可能很乏味——而且通常毫无意义。但您的可能是少数有意义的用例之一。
尽管如此,您仍然必须知道可能丢失列的数据类型。为了本演示的目的,我将假设integer
。否则,您必须额外传递数据类型并相应地构建查询。
CREATE OR REPLACE FUNCTION f_dynamic_select(_tbl regclass
, _cols VARIADIC text[]) -- ①
RETURNS SETOF record -- ② anonymous records
LANGUAGE plpgsql AS
$func$
BEGIN
RETURN QUERY EXECUTE -- ③ dynamic SQL
format(
'SELECT %s FROM %s' -- ④ safe against SQLi
, (
SELECT string_agg(COALESCE(quote_ident(a.attname)
, '0 AS ' || quote_ident(t.col) -- assuming integer!
), ', ' ORDER BY t.ord) -- ⑤
FROM unnest(_cols) WITH ORDINALITY t(col, ord) -- ⑤
LEFT JOIN pg_attribute a ON a.attrelid = _tbl -- ⑥
AND a.attnum > 0
AND NOT a.attisdropped
AND a.attname = t.col
)
, _tbl
);
END
$func$;
打电话(重要!)
SELECT *
FROM f_dynamic_select('static', 'pool', 'spa', 'sauna', 'house_size', 'no_rooms')
AS t(pool int, spa int, house_size int, sauna int, no_rooms int); -- ② column definition list
您的示例调用,使用基于以下列的表达式:
SELECT pool, case when spa = 1 then 1 else 0 end as has_spa -- ⑦ expressions
, sauna, house_size
, case when no_rooms > 2 then 1 else 0 end as rooms
FROM f_dynamic_select('static', 'pool', 'spa', 'sauna', 'house_size', 'no_rooms')
AS t(pool int, spa int, house_size int, sauna int, no_rooms int);
数据库
(1) 该函数将表名作为注册表
类型。看:
...然后是任意的列名列表——按照有意义的顺序。< code>VARIADIC对此应该很方便。参见:
请注意,我们将列名作为区分大小写的单引号字符串传递。不是(双引号)标识符。
(2)这可能是我第一次建议从函数返回匿名记录 - 在[plpgsql]标签上接近1000个答案之后。手册:
如果函数已定义为返回记录
数据类型,则必须存在别名或关键字AS
,然后是(column_namedata_type[,…])
形式的列定义列表。列定义列表必须与函数返回的列的实际数量和类型相匹配。
③动态SQL手册。
④ 对于SQL注入是安全的,因为表名作为<code>regclass</code>传递,并且<code>SELECT</code>列表使用<code>quote_ident()</code>小心地连接。请参见:
(5) 使用 WITH ORDINALITY
以保持列的原始顺序。看:
(6) 左联接
到系统目录pg_attribute
以标识现有列。看:
(7) 将基于传递的列构建的表达式移动到外部 SELECT。
免责声明:如果有必要,我只会介绍这种复杂程度。也许您毕竟可以在每个数据库中使用简单的视图?
问题内容: 我想知道是否可以在SQL Server中运行一个命令/存储的程序,该程序将为我提供包含表中给定数据的列的名称。 因此,如果我要查询,请给我该表中所有包含值75的列。我不希望该行。只是表中的列名…这可能吗? 问题答案: 当您对输出感到满意时,请取消注释。 因此,让我们考虑一个简单的表: 现在,基于上述代码的存储过程: 用法示例: 输出:
函数接受参数。在 Go 中,函数可以返回多个“结果参数”,而不仅仅是一个值。它们可以像变量那样命名和使用。 如果命名了返回值参数,一个没有参数的return语句,会将当前的值作为返回值返回。注意,如果遇到if等代码块和返回值同名,还需要显示写出返回值。 package main import "fmt" func split(sum int) (x, y int) { x = sum *
我有一个包含以下列名的dataframe(对于引用,我只提到了一行)。我希望获得中的最大size_cd。在本例中,具有最大值,即24。我想将列名称中的数字作为返回值返回。 输入数据帧: 必需输出:即后面的部分(因为此列具有最大值) 我将感谢您对此的反馈。
我正在使用laravel Elount数据对象访问我的数据,命名我的表、列、外键/主键等的最佳方式是什么? 我发现,有很多命名惯例。我只是想知道哪一个最适合Laravel雄辩的模特。 我正在考虑以下命名约定: 单数表名(例如:Post) 单列名称(例如:userId-post表中的用户id) 表格名称中多个单词的驼峰式大小写(例如:PostComment、PostReview、PostPhoto)
我正在尝试使用对每一行执行一个函数并创建一个考虑多列的新列,我最初使用的是,但速度非常慢。我希望我的自定义函数中的列列表是一个变量,但除非显式地列出变量名,否则无法使其工作。例如,这是可行的: 但如果我希望它使用列输入作为vars进行计算:
问题内容: 在其他语言(例如R或SQL)中找到该选项的地方,但我不太确定如何在Pandas中进行此操作。 因此,我有一个具有1262列和1行的文件,并且每次出现特定值时都需要返回列标题。 例如说这个测试数据框: 我需要找到列名,例如value = 38.15。最好的方法是什么? 谢谢 问题答案: 看到只有一行,那么您可以调用结果并使用它来屏蔽列: 分解以上内容: 您也可以使用param :