我有一个包含100列的记录的表,我需要根据某种条件(where子句)从该表中获取所有列的不同值的计数。
下面的查询工作正常,但我无法使用where子句。因此,它给出了表中所有记录的结果。但是我希望它基于某种条件,比如说列file_id = 1;。我的问题是如何在以下查询中使用where子句。或者是否还有其他替代方法可以解决此问题。
declare @SQL nvarchar(max)
set @SQL = ''
;with cols as (
select Table_Schema, Table_Name, Column_Name, Row_Number() over(partition by Table_Schema, Table_Name
order by ORDINAL_POSITION) as RowNum
from INFORMATION_SCHEMA.COLUMNS
)
select @SQL = @SQL + case when RowNum = 1 then '' else ' union all ' end
+ ' select ''' + Column_Name + ''' as Column_Name, count(distinct ' + quotename (Column_Name) + ' ) As DistinctCountValue,
count( '+ quotename (Column_Name) + ') as CountValue FROM ' + quotename (Table_Schema) + '.' + quotename (Table_Name)
from cols
where Table_Name = 'table_name' --print @SQL
execute (@SQL)
Run Code Online (Sandbox Code Playgroud)
我之所以使用动态查询,是因为我还需要将该查询重用于其他表。
首先获取列并使用东西以这种方式生成选择:
SELECT COUNT(ColumnA) AS ColumnA, COUNT(ColumnB AS ColumnB), COUNT(ColumnC) AS ColumnC....
Run Code Online (Sandbox Code Playgroud)
这样,您只需在表上选择一次即可获取所有计数,然后,用于CROSS APPLY“取消透视”这些列并在每列的一行上返回输出
CROSS APPLY(
VALUES(1, 'ColumnA', ColumnA), (2, 'ColumnB', ColumnB), (3, 'ColumnC', ColumnC)
)(ID, ColumnName, DistinctCountValue)
Run Code Online (Sandbox Code Playgroud)
对于过滤器,使用sp_executesql并将file_id作为参数发送
exec SP_executesql @SQL, N'@FID INT', @FID = @FileID
Run Code Online (Sandbox Code Playgroud)
由于您正在使用该表的所有列,因此Row_Number() over(partition by Table_Schema, Table_Name order by ORDINAL_POSITION) as RowNum多余,因此ORDINAL_POSITION已经具有您要查找的值
declare @tablename nvarchar(50) = 'MyTestTable'
declare @fileID int = 1
declare @SQL nvarchar(max)
set @SQL = ''
;with cols as (
select TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, ORDINAL_POSITION
from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = @TableName
)
select @SQL = ';WITH CTE AS (SELECT
' +
STUFF((
SELECT ', COUNT(DISTINCT ' + QUOTENAME(COLUMN_NAME) + ') AS ' + QUOTENAME(COLUMN_NAME)
FROM cols
ORDER BY ORDINAL_POSITION
FOR XML PATH('')
), 1, 1, '')
+ '
FROM ' + @TableName + '
WHERE File_ID = @FID
)
SELECT B.*
FROM CTE
CROSS APPLY (
VALUES ' +STUFF((
SELECT ',( ' + CAST(ORDINAL_POSITION AS VARCHAR) + ',' + QUOTENAME(COLUMN_NAME,'''') + ',' + QUOTENAME(COLUMN_NAME) + ')'
FROM cols
ORDER BY ORDINAL_POSITION
FOR XML PATH('')
), 1, 1, '') + '
)B (ID,ColumnName,DistinctCountValue)
'
from cols
exec SP_executesql @SQL, N'@FID INT', @FID = @FileID
Run Code Online (Sandbox Code Playgroud)