SQL: подсчитать количество различных значений в каждом столбце - PullRequest
6 голосов
/ 01 сентября 2009

Мне нужен запрос, который будет возвращать таблицу, в которой каждый столбец представляет собой количество различных значений в столбцах другой таблицы.

Я знаю, как подсчитать разные значения в одном столбце:

select count(distinct columnA) from table1;

Полагаю, я мог бы просто сделать это действительно длинным предложением выбора:

select count(distinct columnA), count(distinct columnB), ... from table1;

но это не очень элегантно и жестко закодировано. Я бы предпочел что-то более гибкое.

Ответы [ 6 ]

3 голосов
/ 01 сентября 2009

попробуйте это (синтаксис sql server 2005):

DECLARE @YourTable table (col1  varchar(5)
                         ,col2  int
                         ,col3  datetime
                         ,col4  char(3)
                         )

insert into @YourTable values ('abcdf',123,'1/1/2009','aaa')
insert into @YourTable values ('aaaaa',456,'1/2/2009','bbb')
insert into @YourTable values ('bbbbb',789,'1/3/2009','aaa')
insert into @YourTable values ('ccccc',789,'1/4/2009','bbb')
insert into @YourTable values ('aaaaa',789,'1/5/2009','aaa')
insert into @YourTable values ('abcdf',789,'1/6/2009','aaa')


;with RankedYourTable AS
(
SELECT
    ROW_NUMBER() OVER(PARTITION by col1 order by col1) AS col1Rank
        ,ROW_NUMBER() OVER(PARTITION by col2 order by col2) AS col2Rank
        ,ROW_NUMBER() OVER(PARTITION by col3 order by col3) AS col3Rank
        ,ROW_NUMBER() OVER(PARTITION by col4 order by col4) AS col4Rank
    FROM @YourTable
)
SELECT
    SUM(CASE WHEN      col1Rank=1 THEN 1 ELSE 0 END) AS col1DistinctCount
        ,SUM(CASE WHEN col2Rank=1 THEN 1 ELSE 0 END) AS col2DistinctCount
        ,SUM(CASE WHEN col3Rank=1 THEN 1 ELSE 0 END) AS col3DistinctCount
        ,SUM(CASE WHEN col4Rank=1 THEN 1 ELSE 0 END) AS col4DistinctCount
    FROM RankedYourTable

ВЫВОД:

col1DistinctCount col2DistinctCount col3DistinctCount col4DistinctCount
----------------- ----------------- ----------------- -----------------
4                 3                 6                 2

(1 row(s) affected)
2 голосов
/ 01 сентября 2009

В этом коде должны быть указаны все столбцы таблицы 'table1' с соответствующим количеством отдельных значений в качестве данных.

DECLARE @TableName VarChar (Max) = 'table1'
DECLARE @SqlString VarChar (Max)

set @SqlString = (
  SELECT DISTINCT
    'SELECT ' + 
        RIGHT (ColumnList, LEN (ColumnList)-1) + 
      ' FROM ' + Table_Name
    FROM INFORMATION_SCHEMA.COLUMNS COL1
      CROSS AppLy (
        SELECT ', COUNT (DISTINCT [' + COLUMN_NAME + ']) AS ' + '''' + COLUMN_NAME + ''''
          FROM INFORMATION_SCHEMA.COLUMNS COL2
          WHERE COL1.TABLE_NAME = COL2.TABLE_NAME
          FOR XML PATH ('')
      ) TableColumns (ColumnList)
    WHERE
      1=1 AND 
      COL1.TABLE_NAME = @TableName
)

EXECUTE (@SqlString)
1 голос
/ 01 сентября 2009

и он жестко закодирован.

Нетрудно предоставить список полей для оператора SQL. Это обычная и приемлемая практика.

0 голосов
/ 03 сентября 2009

Я ценю все ответы. Я думаю, что решение, которое будет работать лучше всего для меня в этой ситуации (подсчет количества различных значений в каждом столбце таблицы из внешней программы, которая не знает о таблице, кроме ее имени), выглядит следующим образом:

Запустите «описать таблицу1» и извлеките имена столбцов из результата.

Просмотрите имена столбцов и создайте запрос для подсчета различных значений в каждом столбце. Запрос будет выглядеть примерно так: «выберите количество (отдельный столбец А), количество (отдельный столбец В), ... из таблицы 1».

0 голосов
/ 01 сентября 2009

Это не обязательно будет возможно для каждого поля в таблице. Например, нельзя выполнить DISTINCT для поля ntext или изображения SQL Server, если вы не приведете их к другим типам данных и не потеряете точность.

0 голосов
/ 01 сентября 2009

DISTINCT это зло. Делать COUNT / GROUP BY

...