假设我的表格中有几列(实际上是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,因为它有大约一百万行...即使如此,我认为旋转也是要走的路。而且由于语法我对此有点害怕。
如果您知道其他方法,请分享。如果您知道如何解决该问题,请教我,大声笑。
谢谢。
答案 0 :(得分:0)
您可以循环访问临时表中的行,并将结果存储在另一个临时表中。
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'
您的代码,但带有指示符已处理,可在计算列时进行注册。
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 将收到一个值。当前行的每个已处理记录更新 isProcessed 都为1。
答案 1 :(得分:0)
您正在寻找的是UNPIVOT。 unpivot-example
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 ;