Использование DISTINCT с функцией COUNT() OVER в SQL Server

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

SQL
Скопировать код
WITH CTE AS (
  SELECT DISTINCT key, category FROM table
)
SELECT 
  category, COUNT(key) OVER (PARTITION BY category) AS distinct_count
FROM CTE;

Использование конструкции CTE помогает нам избежать дублирования записей при подсчёте и получить количество уникальных записей в каждой категории.

Кинга Идем в IT: пошаговый план для смены профессии

Профессиональные альтернативы

Использование DENSE_RANK

SQL
Скопировать код
WITH Ranked AS (
  SELECT 
    key, 
    category, 
    DENSE_RANK() OVER (PARTITION BY category ORDER BY key) AS dr
  FROM table
  WHERE key IS NOT NULL
)
SELECT 
  category, 
  MAX(dr) AS distinct_count
FROM Ranked
GROUP BY category;

Функция DENSE_RANK() позволяет нам определить максимальный ранг, который и будет отображать количество уникальных значений в каждой категории. Запомните, что NULL значения должны обрабатываться отдельно.

SQL Server 2012: Использование DISTINCT совместно с OVER()

В SQL Server 2012 и более поздних версиях появилась возможность использовать COUNT(DISTINCT) с OVER().

SQL
Скопировать код
SELECT 
  category,
  COUNT(DISTINCT key) OVER (PARTITION BY category) AS distinct_count
FROM table;

Эта функциональность доступна для тестирования здесь.

Визуализация

Markdown
Скопировать код
Список гостей (👥): [Алиса, Боб, Чарли, Алиса, Боб]

COUNT() OVER: Подсчёт приглашенных

Markdown
Скопировать код
📨: [👤 + 👤 + 👤 + 👤 + 👤] = 5

COUNT() OVER с DISTINCT: Подсчёт участников вечеринки

Markdown
Скопировать код
🎉: [Алиса, Боб, Чарли] = 3

DISTINCT позволяет учесть каждого гостя только однажды, не принимая во внимание повторения.

Полезные инструменты

OUTER APPLY для обработки пропусков

SQL
Скопировать код
SELECT 
  t.category, 
  dc.DistinctCount
FROM 
  (SELECT DISTINCT category FROM table) t
OUTER APPLY (
  SELECT COUNT(DISTINCT t2.key) AS DistinctCount
  FROM table t2
  WHERE t2.category = t.category
) dc;

Связанные подзапросы как надёжное средство

SQL
Скопировать код
SELECT 
  DISTINCT category, 
  (SELECT COUNT(DISTINCT key) FROM table t2 WHERE t2.category = t1.category) AS distinct_count
FROM table t1;

Группировка с использованием подзапросов

SQL
Скопировать код
SELECT 
  category, 
  (SELECT COUNT(DISTINCT key) FROM table t2 WHERE t2.category = t1.category) AS distinct_count
FROM table t1
GROUP BY category;

Продвинутые методы

Подсчёт с учетом определённых условий

SQL
Скопировать код
SELECT 
  category, 
  COUNT(DISTINCT CASE WHEN condition THEN key ELSE NULL END) OVER (PARTITION BY category) AS conditional_distinct_count
FROM table;

Методы агрегации для более удобного подсчёта

SQL
Скопировать код
SELECT 
  category, 
  (SELECT MIN(key) FROM table WHERE category = t.category AND condition) AS conditional_distinct_count
FROM table t
GROUP BY category;

Полезные материалы

  1. Установка eyeD3 на Webfaction – Stack Overflow — в этом материале подробно рассмотрены тонкости установки eyeD3.
  2. Описание секции OVER (Transact-SQL) – SQL Server | Microsoft Learn — осваивайте возможности команды OVER с помощью учебных материалов от компании Microsoft.
  3. Создание оповещений в Журнале аналитики Microsoft Azure — здесь вы научитесь создавать оповещения в системе Azure Log Analytics.