• You've made a good start. I tend to query each column separately as I'm doing a conversion using templates, especially since value distributions are extremely helpful. Each data type has its quirks and custom aspects to look at. For example, for datetime data, I like to know if it is strictly dates or dates with times. And I like to know if the data fits in a smalldatetime. Knowing empty strings vs. nulls is important too.

    Below is a template I use for imported datetime data interrogation

    -- interrogate DateTime column

    -- to see if it is a Time column, nullable, or an expected range

    select

    COUNT(*) as CountRows,

    sum(case when <colname,,> is null then 1 else 0 end) as NullsCount,

    sum(case when CONVERT(varchar(12), <colname,,>, 114) = '00:00:00:000' then 1 else 0 end) as DateNoTimeCount,

    sum(case when CONVERT(varchar(12), <colname,,>, 114) > '00:00:00:000' then 1 else 0 end) as DateTimeCount,

    sum(case when <colname,,> < '1/1/1900' then 1 else 0 end) as Before1900Count,

    sum(case when <colname,,> between '1/1/1900' and '1/1/2000' then 1 else 0 end) as BetweenCount,

    sum(case when <colname,,> >= '1/1/2000' then 1 else 0 end) as After2000Count

    from

    <tablename,,>

    -- most frequent values

    select top 100

    <colname,,>,

    COUNT(*) as frequencyCount

    from

    <tablename,,>

    group by

    <colname,,>

    having

    COUNT(*) > 1

    order by

    COUNT(*) desc