如何构造一个SQL语句以跨多个平面无关表运行,并显示结果以及选择结果和结果的表名。
这种情况是这样的,我有几个表,每个表具有相同的列名。这是我从外部各方收到的数据,它们原样存储在不同的表中。
相同的表如下所示:
Table 1: pid, parent_name, student_name, student_number, class_name, columnN Table 2: pid, previous_school, previous_school, student_number, columnN Table 3: pid, student_name, student_number, parent_name, column4, columnN Table 14: pid, student_number, parent_name, column4, columnN Table N: pid, previous_school, parent_name, column4, columnN
我需要一个SQL语句,该语句可student_name在所有表中使用伪代码进行搜索:for each table, find a student named john doe and return to me the row where you got the result and the table where you found the result
student_name
for each table, find a student named john doe and return to me the row where you got the result and the table where you found the result
在以下演示文稿中给出结果:
john doe, Table 1, pid john doe, Table 9, pid
更复杂的是,该列student_name可能不在所有表中,因此,如果在该表中找不到该列,则需要仔细进行查询。
您正在寻找动态SQL。从系统目录中自动组装您的查询:
SELECT string_agg('SELECT student_name, ''' || c.oid::regclass || ''' AS tbl, pid FROM ' || c.oid::regclass || $$ WHERE student_name = 'John Doe'$$ , E'\nUNION ALL\n') FROM pg_namespace n JOIN pg_class c ON c.relnamespace = n.oid WHERE n.nspname = 'public' -- schema name where your tables lie AND c.relname LIKE 't%' -- and / or filter table names AND EXISTS ( SELECT 1 FROM pg_attribute WHERE attrelid = c.oid AND attname = 'student_name' -- make sure column exists AND NOT attisdropped -- and is alive );
产生查询字符串:
SELECT student_name, 'tbl1' AS tbl, pid FROM tbl1 WHERE student_name = 'John Doe' UNION ALL SELECT student_name, 'tbl2' AS tbl, pid FROM tbl2 WHERE student_name = 'John Doe' UNION ALL SELECT student_name, 'tbl3' AS tbl, pid FROM tbl3 WHERE student_name = 'John Doe' ...
然后在第二个调用中运行它,或者使用来使用PL / pgSQL函数完全自动化它EXECUTE。示例: 从表中选择一组动态列,并获取每个列的总和
EXECUTE
该查询生成带有经过清理的标识符的 安全 代码,以防止SQL注入。(oid::regclass这里的解释。)
oid::regclass
还有更多相关答案。使用搜索。
顺便说一句,LIKE在student_name LIKE 'John Doe'没有意义。如果没有通配符,请使用=。
LIKE
student_name LIKE 'John Doe'
=