2013-12-15 71 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