luk*_*kik 1 sql postgresql database-design dynamic-sql
如何构造SQL语句以跨多个平面无关表运行,并使用select的结果和结果来自的表的名称显示结果.
这个场景是我有几个表中每个都有相同列名的表.我收集的是来自外部各方的数据,因为它存储在不同的表中.
相同的表格如下:
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
Run Code Online (Sandbox Code Playgroud)
我需要一个student_name在所有表中搜索的SQL语句在伪代码中: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
Run Code Online (Sandbox Code Playgroud)
为了使它有点复杂,列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
);
Run Code Online (Sandbox Code Playgroud)
生成查询字符串:
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'
...
Run Code Online (Sandbox Code Playgroud)
然后在第二次调用中运行它或使用PL/pgSQL函数完全自动化它EXECUTE.示例:
从表中选择一组动态列,并获取每个列的总和
此查询生成安全代码,其中包含防止SQL注入的已清理标识符.(oid::regclass这里的解释.)
有更多相关的答案.使用搜索.
顺便说一句,LIKE在student_name LIKE 'John Doe'是没有意义的.没有通配符,只需使用=.