oracle SQL -如何在多个表中选择一列的最小条目?

f5emj3cl  于 2023-08-03  发布在  Oracle
关注(0)|答案(2)|浏览(105)

我有几个表(都在同一个模式中),它们有一个名为UPLOAD_TIME的列。我试图找到每个表的最小UPLOAD_TIME。
我可以查询SELECT MIN(UPLOAD_TIME) FROM (each_table)。但是有没有更快的方法呢?
现在我们先看两张table:

  • LASER_VISION_VERIFICATIONS(最短上传时间为2020年11月24日)
  • MACHINE_RNR_RECORDS(最短上传时间为2019年2月12日)

我可以得到这样的结果表吗?:
| MIN(MACHINE_RNR_RECORDS.UPLOAD_TIME)| MIN(MACHINE_RNR_RECORDS.UPLOAD_TIME) |
| --| ------------ |
| 2019年2月12日| 12FEB2019 |

fkvaft9z

fkvaft9z1#

您可以合并到单个查询中:

SELECT 'TABLE1' table_name,MIN(upload_time) min_upload_time
          FROM table1
        UNION ALL
        SELECT 'TABLE2' table_name,MIN(upload_time)
          FROM table2
        UNION ALL
        SELECT 'TABLE3' table_name,MIN(upload_time)
          FROM table3

字符串
但这并不会比对每个表运行独立查询快得多。唯一的优点是共享解析和更少的网络往返,这在这种情况下是无关紧要的。如果您关心速度,您将需要确保upload_time在每个表中都被索引。缺点是它不适合扩展性-如果添加表,则必须修改查询。如果你的表列表可能会随着时间的推移而增长,你最好使用PL/SQL脚本和循环:

CREATE OR REPLACE TYPE result_rowtype IS OBJECT (table_name varchar2(128),
                                                 min_upload_time date);

CREATE OR REPLACE TYPE result_tabtype IS TABLE OF result_rowtype;

CREATE OR REPLACE FUNCTION myearliestdatecol(in_column_name IN varchar2)
  RETURN result_tabtype PIPELINED
AS
  rec_result_row result_rowtype;
BEGIN
  FOR rec_table IN (SELECT table_name
                      FROM user_tab_columns
                     WHERE column_name = in_column_name)
  LOOP
    EXECUTE IMMEDIATE 'SELECT result_rowtype('''||rec_table.table_name||''',
                                             MIN("'||in_column_name||'"))
                         FROM "'||rec_table.table_name||'"' 
                 INTO rec_result_row;

    PIPE ROW (rec_result_row);       
  END LOOP;
END;


现在查询它:

SELECT *
  FROM TABLE(myearliestdatecol('UPLOAD_TIME'))


如果添加或删除更多表,则无需修改代码。您还可以将此方法用于不同的日期列,这样就可以在不修改代码的情况下更改列名。

ctzwtxfj

ctzwtxfj2#

为此,您需要使用动态SQL

DECLARE
  mystr VARCHAR(1000);
  v_mystamp TIMESTAMP(6);
  cursor c1 is 
    select distinct data_table from table_list order by data_table asc;
 
  
BEGIN
FOR rec IN c1 LOOP
     mystr := 'select min(UPLOAD_TIME) from ' || rec.data_table;
 
     execute immediate mystr into v_mystamp ;
     DBMS_OUTPUT.PUT_LINE(rec.data_table);
     DBMS_OUTPUT.PUT_LINE(v_mystamp);
   END LOOP;
END;

字符串

相关问题