在数据库或表格中查找最大数字?

时间:2017-09-25 06:45:19

标签: sql sql-server tsql

我有一个包含大约150个表的数据库。在某些地方,有一个值导致错误太大(是的,该列可能应该更正!) - 问题是我不知道问题出现在哪个表中。在150个表中......它可能是10-15个表中较小的集合,这可能是问题所在。

但是这15个表中的每个表都有多个数字列,并且为每列写入多个ORDER BY非常耗时。

有没有办法按表或整个数据库中的最大数值排序而不指定手工哪个列?

修改

对于没有阅读评论的人 - 具体问题已经解决。但我仍然想知道是否有查询要做。

2 个答案:

答案 0 :(得分:1)

这是一种快速而肮脏的方法,通过构建一个巨大的T-SQL语句来查询所有列(结果可以用Excel熟练地检查)。如果您的数据库很大,那么效率极低;一个明显的优化是获得每个表而不是每列的所有列的最大值,这至少减少了表扫描。 (另一个是单独获取所有查询并在带有EXEC的游标循环中执行它们;我将其作为练习留给读者。)它确实演示了一些动态SQL的常用技术。

SELECT REPLACE(STUFF((
    SELECT '|' + REPLACE(REPLACE(REPLACE(REPLACE(
        'SELECT $tn AS [table], $cn AS [column], CONVERT(NVARCHAR(MAX), MAX($c)) AS [max_value] FROM $t',
        '$tn', QUOTENAME(t.[name], '''')),
        '$cn', QUOTENAME(c.[name], '''')),
        '$t', QUOTENAME(t.[name])),
        '$c', QUOTENAME(c.[name]))
    FROM sys.tables t
    JOIN sys.columns c on c.[object_id] = t.[object_id]
    -- All numeric types
    WHERE c.system_type_id in (48, 52, 56, 59, 60, 62, 106, 108, 122, 127) 
    AND t.is_ms_shipped = 0
    FOR XML PATH('')), 1, 1, ''),
    '|', 
    ' UNION ALL ' 
)

同样的想法,但现在一次查询所有列,每个表给出一个查询:

SELECT q FROM (
    SELECT q = 'SELECT ' + QUOTENAME(t.[name], '''') + ' AS [table]' + (
        SELECT ', MAX(' + QUOTENAME(c.[name]) + ') AS ' + QUOTENAME(c.[name])
        FROM sys.columns c 
        WHERE c.[object_id] = t.[object_id]
        -- All numeric types
        AND c.system_type_id IN (48, 52, 56, 59, 60, 62, 106, 108, 122, 127) 
        FOR XML PATH('')
    ) + ' FROM ' + QUOTENAME(t.[name]) + ';'
    FROM sys.tables t
    WHERE t.is_ms_shipped = 0
) _
WHERE q IS NOT NULL

Management Studio不喜欢在网格中显示大量查询,因此在一个窗口中执行那么多查询时,请务必使用“结果文本”(Ctrl-T)。这是一个UI问题,而不是数据库问题。

答案 1 :(得分:0)

我不知道它是否是最佳解决方案,但使用此代码,您可以在表格中找到最大的数值。 我找到了表中的所有数字列,然后是每行的MAX值,最后是最大值。

create table myTable (
    id int identity(1,1)
    ,num1 int
    ,num2 int
    ,str1 varchar(3)
    ,str2 varchar(3)
    ,num3 int
    ,num4 bigint
    ,num5 decimal(5,2)
    ,str3 varchar(3)
);

insert into myTable values
(12,65,'A','A',6589,222,65.23,'A')
,(54,752,'B','B',212,74,1.23,'B')
,(36,75,'C','C',23,7,123.4,'C')
,(3,32,'D','D',238,786,36.74,'D')
,(7772,45,'E','E',563,42,4.23,'E')

DECLARE @columns AS nvarchar(255)
DECLARE @sql AS nvarchar(755)


;WITH CTE_numericColumns AS (
    SELECT
        COLUMN_NAME
        --,DATA_TYPE
        --,CASE WHEN column_id IS NULL THEN 0 ELSE 1 END AS [Identity]
    FROM INFORMATION_SCHEMA.COLUMNS
    LEFT JOIN sys.identity_columns
        ON OBJECT_ID(TABLE_NAME) = [object_id]
        AND COLUMN_NAME = [name]
    WHERE 1 = 1
        AND TABLE_NAME='MyTable'
        AND DATA_TYPE IN ('tinyint', 'smallint', 'int', 'bigint', 'decimal', 'numeric', 'float', 'real')
        AND [column_id] IS NULL
)
SELECT @columns = STUFF((SELECT ',(' + COLUMN_NAME + ')' FROM CTE_numericColumns FOR XML PATH('')), 1, 1, '')


SET @sql = '
    ;WITH CTE_MaxValue AS (
        SELECT(SELECT MAX([MaxValue])
            FROM (VALUES ' + @columns + ') AS [Values](MaxValue)) AS MaxValue
        FROM [MyTable]
    ) SELECT MAX(MaxValue) AS [MaxNumValue] FROM CTE_MaxValue'


exec sp_executesql @sql