簡體   English   中英

SQL - 為每列選擇最小值和最大值

[英]SQL - Select min and max value for each column

假設我有一個包含幾列(實際上是 107 列)的表:COLUMN_A、COLUMN_B、COLUMN_C、COLUMN_D 等...

在他們每個人中,我想提取諸如最小/最大長度、空+空數量和最小/最大值之類的信息。

要單獨分析每一列,我使用以下代碼:

DECLARE @col VARCHAR(max) =   'COLUMN_A'

DECLARE @RUN_QUERY AS VARCHAR(MAX)
SET @RUN_QUERY = 'SELECT MIN(LEN(' + @col + ')) AS CHR_MIN, MAX(LEN(' + @col + ')) AS CHR_MAX, MIN(' + @col + ') AS VALUE_MIN, MAX(' + @col + ') AS VALUE_MAX FROM MY_TABLE'
EXEC(@RUN_QUERY)

我可以手動更改第一行的變量,以便“有效”更改目標列。

我也知道訪問 INFORMATION_SCHEMA 我可以很容易地得到一個表,每一列都是一行,下面的腳本:

SELECT TABLE_NAME, COLUMN_NAME, ORDINAL_POSITION
INTO #TEMP_COLS
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = MY_TABLE
ORDER BY 3

但我不知道如何為 #TEMP_COLS 表的每一行運行第一個查詢......我覺得我需要一個數據透視表,但我不知道從哪里開始。 我當然不能將 MY_TABLE 作為一個整體旋轉,因為它有大約 50 萬行……即便如此,我認為旋轉是要走的路。 由於語法,我有點害怕它。

如果您知道任何其他方式,請分享。 如果你知道如何解決這個問題,請教我,哈哈。

提前致謝。

您可以循環臨時表的行並將結果存儲在另一個臨時表中。

IF OBJECT_ID('tempdb..#TEMP_COLS') IS NOT NULL
    DROP TABLE #TEMP_COLS
SELECT TABLE_NAME, COLUMN_NAME, ORDINAL_POSITION, CAST(0 as BIT) as isProcessed
INTO #TEMP_COLS
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'YourTable'

您的代碼但帶有指示器isProcessed以在計算列時進行注冊。

DECLARE @RUN_QUERY AS VARCHAR(MAX)
DECLARE @col VARCHAR(max) =  (SELECT TOP 1 COLUMN_NAME FROM #TEMP_COLS WHERE isProcessed = 0)

IF OBJECT_ID('tempdb..#MinMaxValues') IS NOT NULL
    DROP TABLE #MinMaxValues
CREATE TABLE #MinMaxValues (
    COLUMN_NAME VARCHAR(max),
    CHR_MIN int,
    CHR_MAX int,
    VALUE_MIN VARCHAR(max),
    VALUE_MAX VARCHAR(max),
)

WHILE @col IS NOT NULL
BEGIN

    SET @RUN_QUERY = '
    INSERT INTO #MinMaxValues
    SELECT  ''' + @col + ''',
            MIN(LEN(' + @col + ')) AS CHR_MIN, 
            MAX(LEN(' + @col + ')) AS CHR_MAX, 
            MIN(' + @col + ') AS VALUE_MIN, 
            MAX(' + @col + ') AS VALUE_MAX 
            FROM YourTable
    GROUP BY ' + @col
    EXEC(@RUN_QUERY)

    UPDATE #TEMP_COLS SET isProcessed = 1 WHERE COLUMN_NAME = @col
    SET @col = null
    SELECT TOP 1 @col = COLUMN_NAME FROM #TEMP_COLS WHERE isProcessed = 0
END


SELECT * from #MinMaxValues

#MinMaxValues 的臨時表聲明。 當我們遍歷每個#TEMP_COLS 記錄時,該表將存儲每一列的結果。

迭代可能是一個游標,但由於游標非常慢,我更喜歡迭代#TEMP_COLS 中的每條記錄,而我們的指標isProcessed為 0,這意味着@col將收到一個值。 每個處理過的記錄更新都是對值為 1 的當前行進行處理。

您正在尋找的是 UNPIVOT。 逆透視示例

DROP TABLE IF EXISTS yourTable; 

CREATE TABLE yourTable (
    COL_01 INT NULL
  , COL_02 INT NULL
  , COL_03 INT NULL
  , COL_04 INT NULL
  , COL_05 INT NULL
  , COL_06 INT NULL
  , COL_07 INT NULL
  , COL_08 INT NULL
  , COL_09 INT NULL
  , COL_10 INT NULL
  , COL_11 INT NULL
  , COL_12 INT NULL
  , COL_13 INT NULL
  , COL_14 INT NULL
  , COL_15 INT NULL
) ;
GO

INSERT INTO dbo.yourTable (COL_01
                           , COL_02
                           , COL_03
                           , COL_04
                           , COL_05
                           , COL_06
                           , COL_07
                           , COL_08
                           , COL_09
                           , COL_10
                           , COL_11
                           , COL_12
                           , COL_13
                           , COL_14
                           , COL_15
)
VALUES (
   CAST ((RAND()*100) AS INT)
  ,CAST ((RAND()*100) AS INT)
  ,CAST ((RAND()*100) AS INT)
  ,CAST ((RAND()*100) AS INT)
  ,CAST ((RAND()*100) AS INT)
  ,CAST ((RAND()*100) AS INT)
  ,CAST ((RAND()*100) AS INT)
  ,CAST ((RAND()*100) AS INT)
  ,CAST ((RAND()*100) AS INT)
  ,CAST ((RAND()*100) AS INT)
  ,CAST ((RAND()*100) AS INT)
  ,CAST ((RAND()*100) AS INT)
  ,CAST ((RAND()*100) AS INT)
  ,CAST ((RAND()*100) AS INT)
  ,CAST ((RAND()*100) AS INT)
) ;
GO 20

SELECT TOP (100) * FROM dbo.yourTable

逆透視代碼

SELECT
    unpvt.ColumnName
  , MAX( ColumnValue )
  , MIN( ColumnValue )
  , AVG( ColumnValue )
FROM (
    SELECT
        COL_01
      , COL_02
      , COL_03
      , COL_04
      , COL_05
      , COL_06
      , COL_07
      , COL_08
      , COL_09
      , COL_10
      , COL_11
      , COL_12
      , COL_13
      , COL_14
      , COL_15
    FROM dbo.yourTable
) p
    UNPIVOT (
        ColumnValue
        FOR ColumnName IN (COL_01, COL_02, COL_03, COL_04, COL_05, COL_06, COL_07, COL_08, COL_09, COL_10, COL_11
                           , COL_12, COL_13, COL_14, COL_15
        )
    ) AS unpvt
GROUP BY unpvt.ColumnName ;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM