表列的平均长度

时间:2014-07-30 16:07:25

标签: mysql

我有一个包含50多个VARCHAR(255)列的表 主持人报告说,在少数字段中,有些内容在250个字符之后被删除。

如果选中,这是VARCHAR(255)的预期行为,我必须将某些字段更新为text。但问题是他们无法向我提供有关哪些领域出现问题的细节/指示。

所以我最好的猜测是分析当前数据并找到通常存储长内容的列。

我可以使用一个好的查询结构来获取:
  - 每列的AVG长度   - 每列的最大长度   - 此列的长度为200+的行数。

4 个答案:

答案 0 :(得分:7)

SELECT AVG(CHAR_LENGTH(col)) avg_length,
       MAX(CHAR_LENGTH(col)) max_length,
       COUNT(CASE WHEN CHAR_LENGTH(col) >= 200 THEN 1 ELSE NULL END) 200_plus_count
  FROM tbl;

答案 1 :(得分:1)

我最近有理由实现这一点。使用与Arth和VMai的答案类似的逻辑,我构建了一个存储过程来获取表的所有列大小。

DELIMITER //
CREATE PROCEDURE ColumnSizeForTable(TableName varchar(64), SchemaName varchar(64))
BEGIN
SELECT @@group_concat_max_len INTO @group_concat_max;
SET SESSION group_concat_max_len = 100000;
SELECT 
    CONCAT('SELECT TRIM(TRAILING \' UNION ALL \' FROM CAST(CONCAT(',
        GROUP_CONCAT(
            CONCAT(
                CONCAT('\'SELECT \\\'', COLUMN_NAME, '\\\' ColName,\''),
                ', ',
                CONCAT('IFNULL(AVG(CHAR_LENGTH(',COLUMN_NAME,')),\'0\'), \' ColAverage,\''),
                ', ',
                CONCAT('IFNULL(MAX(CHAR_LENGTH(',COLUMN_NAME,')),\'0\'), \' ColMaximum,\''),
                ', ',
                CONCAT('IFNULL(COUNT(CASE WHEN CHAR_LENGTH(',COLUMN_NAME,') >= 200 THEN 1 ELSE NULL END),\'0\'), \' Col200Plus UNION ALL \'')
            )
        ),
        ') AS CHAR)) INTO @unionquery FROM ',
        TABLE_NAME,
        ';')
INTO @columnquery FROM
    INFORMATION_SCHEMA.COLUMNS
WHERE
    TABLE_NAME = TableName
        AND TABLE_SCHEMA = SchemaName
GROUP BY TABLE_NAME;

PREPARE columnsizestmnt FROM @columnquery;
EXECUTE columnsizestmnt;
PREPARE unionstmnt FROM @unionquery;
EXECUTE unionstmnt;
SET SESSION group_concat_max_len = @group_concat_max;
END //
DELIMITER ;

CALL ColumnSizeForTable('TABLENAME','SCHEMANAME');

这是如何运作的:

  1. 增加会话变量group_concat_max_len,这样我们就不必担心GROUP_CONCAT会被切断。
  2. 执行构建另一个查询的concat查询。
    • 第一个查询填充列名称。
    • 生成的查询将放入@columnquery
  3. 执行@columnquery。这构建了查询以将数据放入可读格式
    • 第二个查询获取列数据,包括平均值,最大值和200+计数。
    • 与VMai的答案类似,如果我们没有从中构建另一个查询,那么它将是一个扁平化的结果集。
    • 生成的查询将放入@unionquery
  4. 执行@unionquery。该SELECT输出给用户。它以单一可读格式返回我们尝试收集的列详细信息。

答案 2 :(得分:0)

对于平均选择AVG(长度(column_name))和最大选择MAX(长度(column_name)),对于计数200+,从表WHERE len(rows)=> 200中选择COUNT(column_name)。这个网站应该帮助你解决其他与sql相关的问题,希望我回答你的问题:)

答案 3 :(得分:0)

我建立在Arths的良好答案并整合我的评论。此查询应构建要执行的查询

SELECT
    CONCAT(
        -- The `SELECT` keyword
        'SELECT ',
        -- we build our list of analyzing columns with a GROUP_CONCAT
    GROUP_CONCAT(
    CONCAT (
        -- of the columns from Arths answer
        CONCAT ('AVG(CHAR_LENGTH(', COLUMN_NAME, ')) AVG_', COLUMN_NAME), ', ', 
        CONCAT ('MAX(CHAR_LENGTH(', COLUMN_NAME, ')) MAX_', COLUMN_NAME), ', ', 
        CONCAT ('COUNT((CASE WHEN CHAR_LENGTH(', COLUMN_NAME, ') >= 200 THEN 1 ELSE NULL END) 200_plus_', COLUMN_NAME)      
    ), ' '),
    -- and add the FROM clause
    ' FROM ',
    TABLE_NAME,
    ';' )

FROM
    INFORMATION_SCHEMA.COLUMNS
WHERE
    -- replace it by your own
    TABLE_NAME = 'example10'
GROUP BY
    TABLE_NAME;

注意

格式不是很好,但是,的搜索和,\n用notepad ++等编辑器替换会使语句可读。因此,您将错过手写这个并且不会犯错误的烦人任务。