搜索多个表,并在结果行中显示表名

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可能不在所有表中,因此如果在那里找不到列,则查询需要优雅地进行.

Erw*_*ter 5

您正在寻找动态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这里的解释.)

有更多相关的答案.使用搜索.

顺便说一句,LIKEstudent_name LIKE 'John Doe'是没有意义的.没有通配符,只需使用=.