Oracle PL / SQL查找每列的最大值和最小值

时间:2013-12-15 21:04:50

标签: sql oracle

这里的第一个问题,感谢提前做出的所有回复。我正在尝试创建一个PL / SQL代码,它将为表中的每个变量找到max和min。该表非常大,约有100多个变量和超过百万条记录。

编辑:我想创建一个循环而不是一个select语句,我必须为每列输入max和min 100+次。

理想情况下,我计划从用户统计信息表中获取列名,并使用select语句作为变量,然后从表中创建每个这些变量的select max和min的循环。

此外,该表具有不同类型的列。所以我还需要找到一种方法来过滤掉其他不是数字的类型。

再次感谢以下所有回复。

3 个答案:

答案 0 :(得分:1)

SELECT MIN( column001 ) AS min_column001,
       MAX( column001 ) AS max_column001,
       MIN( column002 ) AS min_column002,
       MAX( column002 ) AS max_column002,
       MIN( column003 ) AS min_column003,
       MAX( column003 ) AS max_column003,
       MIN( column004 ) AS min_column004,
       MAX( column004 ) AS max_column004,

...

       MIN( column099 ) AS min_column099,
       MAX( column099 ) AS max_column099,
       MIN( column100 ) AS min_column100,
       MAX( column100 ) AS max_column100
FROM   YourTable;

答案 1 :(得分:1)

您可以动态生成从表中选择所有列所需的SQL

  SELECT 'SELECT '
          || LISTAGG( 'MIN("' || COLUMN_NAME || '") AS "MIN_' || COLUMN_NAME || '"'
                  || ',MAX("' || COLUMN_NAME || '") AS "MAX_' || COLUMN_NAME || '"'
                , ',' ) WITHIN GROUP ( ORDER BY COLUMN_ID )
          || ' FROM TBL'
  FROM   USER_TAB_COLUMNS
  WHERE  TABLE_NAME = 'YOURTABLENAME';

然后可以复制并运行,以输出每列的最小值和最大值。

如果你坚持要动态地执行它(假设各种列的数据类型不同):

SQL Fiddle

Oracle 11g R2架构设置

CREATE TABLE tbl (
  asdfghjkl NUMBER,
  poiuytrew VARCHAR2(3),
  oiuytrewq DATE,
  sdfghjkla NUMBER,
  zxcvbnmcv NUMBER,
  mnbvcxznb NUMBER,
  qwertyuio NUMBER,
  wertyuiop NUMBER
);

INSERT INTO tbl
SELECT LEVEL, LPAD( TO_CHAR( LEVEL ), 3, '0' ), TRUNC( SYSDATE ) - LEVEL, LEVEL+1, 10-LEVEL, LEVEL, ABS(5-LEVEL), POWER( 0.9, LEVEL )
FROM   DUAL
CONNECT BY LEVEL < 10;

CREATE TABLE test AS SELECT * FROM tbl WHERE 1 = 0;

查询1

SELECT * FROM tbl

<强> Results

| ASDFGHJKL | POIUYTREW |                       OIUYTREWQ | SDFGHJKLA | ZXCVBNMCV | MNBVCXZNB | QWERTYUIO |   WERTYUIOP |
|-----------|-----------|---------------------------------|-----------|-----------|-----------|-----------|-------------|
|         1 |       001 | December, 15 2013 00:00:00+0000 |         2 |         9 |         1 |         4 |         0.9 |
|         2 |       002 | December, 14 2013 00:00:00+0000 |         3 |         8 |         2 |         3 |        0.81 |
|         3 |       003 | December, 13 2013 00:00:00+0000 |         4 |         7 |         3 |         2 |       0.729 |
|         4 |       004 | December, 12 2013 00:00:00+0000 |         5 |         6 |         4 |         1 |      0.6561 |
|         5 |       005 | December, 11 2013 00:00:00+0000 |         6 |         5 |         5 |         0 |     0.59049 |
|         6 |       006 | December, 10 2013 00:00:00+0000 |         7 |         4 |         6 |         1 |    0.531441 |
|         7 |       007 | December, 09 2013 00:00:00+0000 |         8 |         3 |         7 |         2 |   0.4782969 |
|         8 |       008 | December, 08 2013 00:00:00+0000 |         9 |         2 |         8 |         3 |  0.43046721 |
|         9 |       009 | December, 07 2013 00:00:00+0000 |        10 |         1 |         9 |         4 | 0.387420489 |

查询2

DECLARE
  min_sql CLOB;
  max_sql CLOB;
  min_rec tbl%ROWTYPE;
  max_rec tbl%ROWTYPE;
BEGIN
  -- Generate the SQL to find the minimums
  SELECT 'SELECT '
          || LISTAGG( 'MIN("' || COLUMN_NAME || '")', ',' )
                WITHIN GROUP ( ORDER BY COLUMN_ID )
          || ' FROM TBL'
  INTO   min_sql
  FROM   USER_TAB_COLUMNS
  WHERE  TABLE_NAME = 'TBL';

  -- Generate the SQL to find the maximums
  SELECT 'SELECT '
          || LISTAGG( 'MAX("' || COLUMN_NAME || '")', ',' )
                WITHIN GROUP ( ORDER BY COLUMN_ID )
          || ' FROM TBL'
  INTO   max_sql
  FROM   USER_TAB_COLUMNS
  WHERE  TABLE_NAME = 'TBL';

  -- Execute the SQL to find the minimums and put the
  -- results into a %ROWTYPE record (to ensure dataypes
  -- match).
  EXECUTE IMMEDIATE min_sql INTO min_rec;

  -- Execute the SQL to find the maximums and put the
  -- results into a %ROWTYPE record (to ensure dataypes
  -- match).
  EXECUTE IMMEDIATE max_sql INTO max_rec;

  -- Do something with the minimums
  INSERT INTO test VALUES min_rec;

  -- Do something with the maximums
  INSERT INTO test VALUES max_rec;
END;

查询3

SELECT * FROM test

<强> Results

| ASDFGHJKL | POIUYTREW |                       OIUYTREWQ | SDFGHJKLA | ZXCVBNMCV | MNBVCXZNB | QWERTYUIO |   WERTYUIOP |
|-----------|-----------|---------------------------------|-----------|-----------|-----------|-----------|-------------|
|         1 |       001 | December, 07 2013 00:00:00+0000 |         2 |         1 |         1 |         0 | 0.387420489 |
|         9 |       009 | December, 15 2013 00:00:00+0000 |        10 |         9 |         9 |         4 |         0.9 |

答案 2 :(得分:0)

为避免必须输入所有列名,请执行以下查询:

SELECT 'min('||column_name||'), max('||column_name||'), '
FROM user_tab_cols
WHERE table_name = 'myTableName';

然后将结果复制到查询缓冲区中并围绕它构建其余查询。那就是:

  • 在第一行
  • 之前添加select
  • 添加from您想要的任何表格
  • 删除最后一个逗号

您也可以通过选择列名称来执行此操作:

SELECT column_name
FROM user_tab_cols
WHERE table_name = 'myTableName';

将输出复制到Excel(或您喜欢的电子表格)并使用公式生成代码。