2013-12-15 69 views
0

在这里第一个问题,感谢事先所有的答复。我正在尝试创建一个PL/SQL代码,它将查找表中每个变量的最大值和最小值。该表格非常大,约100多个变量和超过百万条记录。的Oracle PL/SQL找到最大和最小每列的

编辑:我想创建一个循环,而不是一个select语句,我将不得不为每一列键入最大和最小100+倍。

理想情况下,我是刨了SELECT语句作为变量来从用户那里获取的统计数据表中的列名,然后创建选择最大值和最小值从表中这些变量中的每一个的循环。

另外,表中有不同类型的列。所以我也需要找到一种方法来过滤掉其他不是数字的类型。再次

感谢下面的所有响应。

+1

欢迎来到SO。请阅读这些链接(http://stackoverflow.com/questions/how-to-ask http://sscce.org/),了解如何发布问题。这样你会得到更好的结果。 http://stackoverflow.com/help/on-topic为什么你认为你需要使用PL/SQL而不是一个简单的SQL select语句? – OldProgrammer

+0

请注意,我想创建一个循环,而不是输入max和min 100+次。列名也非常不同。 – user3105364

+0

查看user_tab_columns视图并创建一个动态SQL字符串以使用EXECUTE IMMEDIATE执行。 – OldProgrammer

回答

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; 
+0

每个列的名称是不同的,我想创建一个循环,它将只为所有的列名执行。谢谢。 – user3105364

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(或您最喜欢的电子表格)中d使用公式生成代码。

1

可以动态地生成需要从表中

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。

如果你在做这一切的动态再坚持(假设各列不同的数据类型):

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 | 
+0

非常感谢。 – user3105364

+0

这工作很好!非常感谢。 如果我想取出非整数列,你会推荐什么? – user3105364

+0

如果您正在为表格选择每一列,那么无论您有不同的数据类型还是相同的数据类型,都可以使用相同的技术。如果你选择一个表的列的子集,那么你可以创建一个只有该子集的记录,并在该记录中构建SQL和'SELECT'或'EXECUTE IMMEDIATE'。如果数据类型相同,另一种方法是从'USER_TAB_COLUMNS'获取列名并在'FOR'循环中运行多个'SELECT ... INTO ...'语句。我仍然建议在运行时对列名进行硬编码,而不是使用动态查询。 – MT0